如何解决React 钩子 useState 没有正确更新
我有一个关于 react + mobx + hooks API 没有正确更新状态的奇怪问题
这是下面示例的控制台输出。没关系 findDomNode 错误,与 toast 组件库过时有关
假设有一个服务列表和一组相应的 id。这是一个管理面板,我想在其中添加或删除服务器端的当前服务。我将选定的服务(即复选框)存储在 useState
中。也可以从后端删除服务,因此我需要使用后端响应中的内容更新前端的选定(复选框)列表
问题是显示更新就在 useEffect
内部的钩子,但在渲染函数 (handleListColCallback
) 内部 selected
的值没有更新,始终保留已删除的值
尝试了useMemo
、useCallback
等的多种组合,结果总是一样。我做错了什么吗?
const AdminServices = observer(() => {
const [selected,setSelected] = useState([]);
const serviceContext = useContext(ServiceStoreContext);
const handleListColCallback = async (params) => {
if (params.type === 'select-checkBox') {
// STEP 3 - I want to manipulate with state removing or adding checked id to array
// ERROR here - selected state still showing old value (not the same as in useEffect)
console.log('checkBox select',selected);
} else if (params.type === 'delete-from-node') {
// STEP 1 - I call delete action,it runs successfully
await serviceContext
.deleteFromNode({ service_id: params.id })
}
};
useEffect(() => {
// STEP 2 - when mobx store updates,I want to reset component state with new values
setSelected(serviceContext.nodeListArrayIds);
},[serviceContext.nodeListArrayIds]);
useEffect(() => {
// selected shows current values (this effect is just for testing)
console.log('selected updated',selected);
},[selected]);
}
更新
问题已通过使用以下 setState 和 handleListColCallback
更新解决。如果有人能解释为什么纯 setState
与 setState((curState) => ... )
useEffect(() => {
setSelected(() => {
return [...serviceContext.nodeListArrayIds];
});
},[serviceContext.nodeListArrayIds]);
} else if (params.type === 'select-checkBox') {
setSelected((selected) => {
const index = selected.indexOf(params.id);
if (index === -1) {
return [...selected,...[params.id]];
} else {
return selected.filter((x) => x !== params.id);
}
});
解决方法
上下文中的数组 (serviceContext.nodeListArrayIds
) 似乎以某种方式重新添加了已删除的项目(OP 可能想要调查的内容)。
setSelected(serviceContext.nodeListArrayIds);
和 setSelected([...serviceContext.nodeListArrayIds]);
之间的区别在于,在第一种情况下,selected
是对 serviceContext.nodeListArrayIds
的引用,因此将反映对它的任何更改。 [...serviceContext.nodeListArrayIds]
创建一个浅层克隆(类似于 .slice()
),因此对 serviceContext.nodeListArrayIds
的更改不会影响它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。