React/Redux中深度克隆对象数组丢失元素问题排查
问题原因分析:浏览器控制台惰性求值 + 后续代码对副本的修改
这事儿我之前排查过好几次,核心问题出在浏览器控制台的惰性求值特性,再结合你代码里后续对projectArr的修改,才会出现这种看似矛盾的打印结果,咱们具体拆解:
1. 浏览器控制台的惰性求值机制
浏览器控制台在打印引用类型(比如数组、对象)时,不会立刻把对象的所有属性值都序列化并显示出来,而是只保存一个指向该对象的引用。只有当你主动点击展开这个对象/数组,或者控制台需要渲染它的时候,才会去读取该对象的当前最新值,而不是执行console.log那一刻的值。
2. 结合你的代码场景分析
看你的代码片段:
case actionTypes.UPDATE_PROJECT: const projectArr = JSON.parse(JSON.stringify(state.projects)); console.log(projectArr); // 单独打印 console.log("PROJECTS BEFORE UPDATE: ", projectArr, state.projects); // 一起打印 // 👉 这里大概率还有后续修改 projectArr 的代码!
出现差异的具体逻辑是:
- 第一个
console.log(projectArr)执行时,控制台只存储了projectArr的引用,没有立刻读取它的完整值。 - 在这两个
console.log之后,你的代码应该对projectArr做了修改(比如找到目标项目索引后,清空了第二个元素的属性,或者直接替换成空对象)。 - 当你后续查看第一个
console.log的输出时,控制台才去读取projectArr的当前状态——也就是已经被修改后的[{projName: "proj1"}, {}]。 - 而第二个
console.log是在修改前执行的,它会把传入的参数(包括projectArr和state.projects)在那一刻的状态做快照记录,所以显示的是完整的数组。
3. 快速验证方法
你可以在打印时直接序列化projectArr,让控制台显示快照值而非引用:
console.log(JSON.stringify(projectArr)); // 打印序列化后的字符串,查看原始状态 console.log("PROJECTS BEFORE UPDATE: ", JSON.stringify(projectArr), state.projects);
如果序列化后的字符串是完整的[{"projName":"proj1"},{"projName":"proj2"}],就能坐实是控制台惰性求值和后续代码修改导致的问题。另外也可以检查两个console.log之后的代码,肯定能找到修改projectArr的逻辑。
内容的提问来源于stack exchange,提问作者Stoodent
相关产品推荐
相关产品推荐

