调用unCheckAllColums意外更新props与多State值,需仅更新configEdit
问题解决:避免意外修改原引用对象
问题根源
代码里出现configNoEdit和传入的configUser被意外修改,核心原因是引用类型的浅拷贝导致多个变量共享同一内存地址:
- 初始化
initValues时,configEdit和configNoEdit直接赋值configUser,如果configUser是对象/数组,三者会指向同一个内存对象,修改任意一个都会同步影响另外两个。 unCheckAllColums里的{...configEdit}是浅拷贝,仅复制了外层对象,内部的config数组还是原引用,map中直接修改conf.show会改动原对象的属性。
修正后的代码
export function HookConfigsUser(configUser) { // 深拷贝工具函数,让对象完全独立(适合无循环引用的普通对象) const deepCopy = (obj) => JSON.parse(JSON.stringify(obj)); const initValues = { configEdit: deepCopy(configUser), // 独立的可编辑副本 configNoEdit: deepCopy(configUser), // 独立的备份副本 } const [values, setValues] = useState(initValues); const unCheckAllColums = () => { // 浅拷贝外层对象,保留原有属性 let editValue = { ...values.configEdit }; // 处理数组时返回新对象,不修改原引用 let setListEdit = editValue.config.map((conf) => { return { ...conf, show: conf.enableEditShow ? false : true }; }); editValue.config = setListEdit; editValue.isEdit = true; const toSetAllstate = { ...values, configEdit: editValue, }; setValues(toSetAllstate); }; const recoverInfo = () => { setValues({ ...values, // 恢复时也用深拷贝,避免后续修改污染备份 configEdit: deepCopy(values.configNoEdit), }); }; return [unCheckAllColums, recoverInfo]; }
关键修改点说明
- 初始化深拷贝:通过
deepCopy让configEdit、configNoEdit和传入的configUser成为完全独立的对象,彻底切断引用关联。 - 数组处理返回新对象:
map中不再直接修改原conf对象,而是通过扩展运算符创建新对象,确保只改动当前副本的属性。 - 修复语法错误:修正了
toSetAlstate的拼写错误,以及recoverInfo的函数定义语法问题。 - 恢复时的深拷贝:恢复编辑状态时对备份对象也做深拷贝,避免后续编辑操作意外修改备份数据。
内容的提问来源于stack exchange,提问作者Santiago Moreno
相关产品推荐
相关产品推荐

