Redux reducer对象赋值异常:同一状态不同访问路径返回值不一致
问题根本原因
- 违反Redux不可变更新规则
你当前的写法仅对state做了第一层浅拷贝,newState.questions和原state.questions仍然是同一个数组引用,数组内的question对象也和原对象引用完全一致。直接修改引用对象的属性属于直接修改原state的非法操作,会导致Redux的状态比对、更新逻辑异常,最终出现状态不同步的问题。 - 控制台输出不一致的原因
浏览器DevTools打印引用类型时采用惰性求值机制:打印newState时仅保存对象引用,你手动点开查看属性详情时,才会读取内存中该对象的当前值,此时可能后续的reducer执行、其他副作用逻辑已经将open值改回了false,所以预览值和直接打印的属性值不一致。 - 直接赋值
true能正常运行属于巧合
该写法本质还是非法修改原state引用,只是刚好没有后续逻辑覆盖你修改的true值,属于偶发的正常表现,不代表写法本身正确。
解决方案
严格遵循Redux不可变更新规则,逐层拷贝需要修改的嵌套数据,正确写法如下:
case actionTypes.toggle: { const targetIndex = action.questionNumber // 拷贝整个questions数组 const newQuestions = [...state.questions] // 拷贝目标question对象并修改open属性 newQuestions[targetIndex] = { ...newQuestions[targetIndex], open: !state.questions[targetIndex].open } // 生成最终新state return { ...state, questions: newQuestions } }
如果项目使用了Redux Toolkit,内置的immer会自动处理不可变更新,你可以直接写修改语法,不需要手动逐层拷贝。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

