我有状态vacations
,我在useEffect
中的fetch
之后设置它,我有按钮approve
,它将在vacation
状态下更改数据,并且我想在函数handleApprove
中更改数据后重新渲染组件,所以我用初始值false
组成了虚拟状态componentShouldUpdate
,并将其作为useEffect
的依赖项传递,当函数handleApprove
被触发时,isetState
与其值!componentShouldUpdate
相反,但该组件仅在我单击2次时重新渲染,为什么会发生这种情况,以及为什么当isetState
componentShouldUpdate
来自子组件时它工作良好?
function VacationsComponent() {
const [vacations, setVacations] = useState([{}]);
const [componentShouldUpdate, setComponentShouldUpdate] = useState(false);
useEffect(() => {
const getVacations = async () => {
const response = await fetch("http://localhost:8000/get-vacations");
const data = await response.json();
setVacations(data);
};
getVacations();
}, [componentShouldUpdate]);
const handleApprove = async (e, vactionId) => {
(await e.target.value) === "approve"
? fetch(`http://localhost:8000/approve-vacation/${vactionId}`, {
method: "POST",
})
: fetch(`http://localhost:8000/reject-vacation/${vactionId}`, {
method: "POST",
});
setComponentShouldUpdate(!componentShouldUpdate);
};
<button onClick={(e) => handleApprove(e, item._id)}>
APPROVE
</button>
}
这很可能是因为useState钩子异步操作。点击此处阅读更多信息。
你可以更新你的代码,只使用一个状态,像这个
function VacationsComponent() {
const [vacations, setVacations] = useState([{}]);
const getVacations = async () => {
const response = await fetch("http://localhost:8000/get-vacations");
const data = await response.json();
setVacations(data);
};
useEffect(() => {
getVacations();
}, []);
const handleApprove = async (e, vactionId) => {
const slug =
e.target.value === "approve" ? "approve-vacation" : "reject-vaction";
await fetch(`http://localhost:8000/${slug}/${vactionId}`, {
method: "POST",
});
getVacations();
};
<button onClick={(e) => handleApprove(e, item._id)}>APPROVE</button>;
}
将setComponentShouldUpdate(!componentShouldUpdate(放入这样的表中,并删除async/await构造。
此外,设置状态的目的是什么,我看不到布尔值在任何地方被使用。通常在设置状态时,您希望在某个地方更新DOM,尤其是使用布尔值时,它非常适合在屏幕上切换元素。
const handleApprove = (e, vactionId) => {
e.target.value === "approve"
? fetch(`http://localhost:8000/approve-vacation/${vactionId}`, {
method: "POST",
}).then(()=>{
// does this go here if it is approved or when it s rejected
setComponentShouldUpdate(!componentShouldUpdate);
})
: fetch(`http://localhost:8000/reject-vacation/${vactionId}`, {
method: "POST",
}).then(()=>{ setComponentShouldUpdate(!componentShouldUpdate); });
};