React 组件在 setState 之后不会重新渲染



我有状态vacations,我在useEffect中的fetch之后设置它,我有按钮approve,它将在vacation状态下更改数据,并且我想在函数handleApprove中更改数据后重新渲染组件,所以我用初始值false组成了虚拟状态componentShouldUpdate,并将其作为useEffect的依赖项传递,当函数handleApprove被触发时,isetState与其值!componentShouldUpdate相反,但该组件仅在我单击2次时重新渲染,为什么会发生这种情况,以及为什么当isetStatecomponentShouldUpdate来自子组件时它工作良好?


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); });

};