Hello.World
Senior Member
hi các bác, e đang tự học và đang làm 1 website bán hàng: database dùng mongodb, backend e build đơn giản bằng nodejs, frontend thì e làm bằng reactjs + redux toolkit.
e đang làm phần admin board để quản trị user, product, categories gồm mấy chức năng cơ bản như xem, thêm, sửa, xoá. Đến phần update thì e gặp vấn đề:
1. Khi submit dispatch actions thành công và server đã cập nhật và trả về data nhưng react lại không re-render để cập nhật state từ store của redux.
2. Bình thường nếu vào từ pages Categories để xem danh sách danh mục rồi thêm, sửa hoặc xoá danh mục thì không có vấn đề, do data đã được get từ page trước đó là Categories. Nhưng khi vào thẳng link Add hoặc Update Category, ví dụ như: "http://localhost:3000/categories/635b59d7934596f6fb3af548", do k đc get đc data trước đó nên trong mỗi pages Add hoặc Update Category e đều phải chạy hàm getCategories() để get data, có cách nào khắc phục vấn đề này không ạ?
E đã google thử khá nhiều cách nhưng chưa giải quyết được. Văn e hơi lủng củng mong các bác giúp đỡ. Ở dưới là đoạn code của page UpdateCategory, do e thấy page AddCategory và UpdateCagegory chung form nên e tạo 1 form component r truyền thẳng state xuống đó luôn.
2 function getCategories và updateCategory trong apiCalls:
e đang làm phần admin board để quản trị user, product, categories gồm mấy chức năng cơ bản như xem, thêm, sửa, xoá. Đến phần update thì e gặp vấn đề:
1. Khi submit dispatch actions thành công và server đã cập nhật và trả về data nhưng react lại không re-render để cập nhật state từ store của redux.
2. Bình thường nếu vào từ pages Categories để xem danh sách danh mục rồi thêm, sửa hoặc xoá danh mục thì không có vấn đề, do data đã được get từ page trước đó là Categories. Nhưng khi vào thẳng link Add hoặc Update Category, ví dụ như: "http://localhost:3000/categories/635b59d7934596f6fb3af548", do k đc get đc data trước đó nên trong mỗi pages Add hoặc Update Category e đều phải chạy hàm getCategories() để get data, có cách nào khắc phục vấn đề này không ạ?
E đã google thử khá nhiều cách nhưng chưa giải quyết được. Văn e hơi lủng củng mong các bác giúp đỡ. Ở dưới là đoạn code của page UpdateCategory, do e thấy page AddCategory và UpdateCagegory chung form nên e tạo 1 form component r truyền thẳng state xuống đó luôn.
JavaScript:
import FormCategory from "../../../components/FormCategory/FormCategory";
import "./update-category.scss";
import { useEffect, useState } from "react";
import storage from "../../../firebase";
import { ref, uploadBytesResumable, getDownloadURL, deleteObject } from "firebase/storage";
import { getCategories, updateCategory } from "../../../redux/apiCalls";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";
const UpdateCategory = () => {
const { id } = useParams();
const dispatch = useDispatch();
const navigate = useNavigate();
const [inputs, setInputs] = useState({
name: '',
desc: '',
slug: '',
isActive: false
});
const [file, setFile] = useState({});
const [tempURL, setTempURL] = useState("");
const categories = useSelector((state) => state.category.categories);
const category = categories.filter(item => item._id === id)[0];
useEffect(() => {
getCategories(dispatch);
if (category) {
setInputs({
name: category.name,
desc: category.desc,
slug: category.slug,
isActive: category.isActive
});
setTempURL(category.img);
}
}, [categories.length, dispatch]);
const handleOnChange = (e) => {
if (e.target.type === "checkbox") {
setInputs({ ...inputs, [e.target.name]: e.target.checked });
} else {
setInputs({ ...inputs, [e.target.name]: e.target.value });
}
};
const updateImage = () => {
return new Promise((resolve, reject) => {
const fileName = new Date().getTime() + file.name;
const storageRef = ref(storage, fileName);
const uploadTask = uploadBytesResumable(storageRef, file);
// Register three observers:
// 1. 'state_changed' observer, called any time the state changes
// 2. Error observer, called on failure
// 3. Completion observer, called on successful completion
uploadTask.on('state_changed',
(snapshot) => {
// Observe state change events such as progress, pause, and resume
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
},
(error) => {
// Handle unsuccessful uploads
},
async () => {
// Handle successful uploads on complete
// For instance, get the download URL: https://firebasestorage.googleapis.com/...
const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
console.log(downloadURL);
resolve(downloadURL);
delImgFireBase();
}
);
});
};
const delImgFireBase = () => {
// Create a reference to the file to delete
const desertRef = ref(storage, category.img);
console.log("category img", category.img)
// Delete the file
deleteObject(desertRef).then(() => {
console.log("xoa thanh cong", category.img);
}).catch((error) => {
console.error(error);
});
}
const handleOnSubmit = async () => {
const imgURL = tempURL ? tempURL : await updateImage();
const updatedCategory = {
...inputs,
img: imgURL,
};
updateCategory(dispatch, id, updatedCategory);
};
const handleCancel = () => {
navigate("/categories");
}
return (
<div className="update-category">
<FormCategory
file={file}
setFile={setFile}
tempURL={tempURL}
setTempURL={setTempURL}
inputs={inputs}
handleOnChange={handleOnChange}
handleOnSubmit={handleOnSubmit}
handleCancel={handleCancel}
/>
</div>
);
};
export default UpdateCategory;
2 function getCategories và updateCategory trong apiCalls:
JavaScript:
export const getCategories = async (dispatch) => {
dispatch(getCategoryStart());
try {
const res = await userRequest.get("/category/");
dispatch(getCategorySucces(res.data));
} catch {
dispatch(getCategoryFailure());
}
}
export const updateCategory = async (dispatch, id, category) => {
dispatch(updateCategoryStart());
try {
const res = await userRequest.put(`/category/${id}`, category);
dispatch(updateCategorySucces(res.data));
} catch {
dispatch(updateCategoryFailure());
}
}
Last edited: