使用useEffect同步Redux状态到本地state时privateDoc状态未完全更新问题
问题原因及解决方案
1. 补全useEffect依赖项
你当前的useEffect设置了空依赖数组,仅会在组件首次挂载时执行一次。如果redux中的docs数据是组件挂载后才异步请求返回的,首次执行useEffect时docs中还没有对应id的文档数据,if (id in docs)判断不成立,就不会触发setPrivateDoc。
修改示例:
useEffect(() => { let id = props.match.params.docId; if (id in docs) { setPrivateDoc(docs[id].privateDoc); setName(docs[id].name); } }, [props.match.params.docId, props.docs]); // 添加依赖,数据/参数变更时重新执行
2. 校验redux存储的字段名
你提到不管docs[id].privateDoc是true还是false,开关都显示为true,核心原因大概率是你访问的字段名和redux中实际存储的字段名不匹配:比如你修改了组件内变量名为privateDoc,但redux中存储的私有字段还是private,会导致docs[id].privateDoc取到undefined,!undefined的布尔值为true,所以开关的checked属性始终为true。而name字段名前后一致,所以不会出现这个问题。
解决方法: 打印docs[id]确认私有状态的实际字段名,修改为对应字段即可。
3. 优化Switchbox状态更新逻辑
你当前给Switchbox传的变更回调直接取当前闭包中的privateDoc取反,极端情况可能出现闭包导致的状态更新异常,建议改为函数式更新,直接基于最新的前序状态修改:
<Switchbox title="Public document" checked={!privateDoc} function={() => setPrivateDoc(prev => !prev)} // 函数式更新避免闭包问题 />
4. 修复提交逻辑的变量作用域问题
你当前的id变量是在useEffect的作用域中声明的,handleSubmit中访问不到,会导致提交时报错,建议在handleSubmit中单独取值,同时记得阻止表单默认提交行为:
function handleSubmit(event) { event.preventDefault(); const id = props.match.params.docId; if (id in docs) { editDoc(name, privateDoc); } else { createDoc(name, privateDoc); } }
内容的提问来源于stack exchange,提问作者Erik Bent
相关产品推荐
相关产品推荐

