在深度嵌套的Redux Store中添加/替换对象遇到问题
解决Redux嵌套状态更新的两个问题:undefined报错与对象覆盖
嘿,我看了你在Redux状态更新时遇到的问题——先是找不到嵌套键导致的cannot read "enteredSubResourceName" of undefined错误,后来修复后又出现了覆盖原有对象的问题,咱们一步步来搞定它。
你的场景回顾
你想通过扩展运算符更新嵌套的Redux状态树,自动创建不存在的键,期望的最终状态结构是这样的:
state: { physical_machines:{ [state.selectedResource]:{ [state.enteredSubResourceName]:{ "name": state.selectedResourceOption, "value": action.payload.value } } } }
先贴出你现有的代码片段:
Action代码
export function addResourceOption(value) { return function (dispatch) { dispatch(addRsrcOpt(value)) }; }
初始Reducer代码(报错版本)
case ADD_RESOURCE_OPTION: return { ...state, physical_machines:{ ...state.physical_machines, [state.selectedResource]:{ ...state.physical_machines.selectedResource, [state.enteredSubResourceName]:{ [state.selectedResourceOption] : action.payload.value } } } };
问题根源拆解
undefined报错的原因:
当state.physical_machines[state.selectedResource]这个键不存在时,你直接尝试展开state.physical_machines.selectedResource(这里还犯了个小错误:动态键应该用方括号取值,而非点语法),此时这个值是undefined,扩展运算符无法处理undefined,自然就抛出了错误。对象被覆盖的原因:
你在更新[state.enteredSubResourceName]对应的对象时,没有展开它原有的内容,直接替换成了只包含新键值对的对象,原有内容自然被完全覆盖。
修复后的Reducer代码
case ADD_RESOURCE_OPTION: // 先缓存各层级的已有数据,不存在则用空对象兜底 const currentSelectedResource = state.physical_machines[state.selectedResource] || {}; const currentSubResource = currentSelectedResource[state.enteredSubResourceName] || {}; return { ...state, // 保留最外层状态的其他内容 physical_machines:{ ...state.physical_machines, // 保留physical_machines层的其他已有对象 [state.selectedResource]:{ ...currentSelectedResource, // 保留selectedResource对应的已有内容(兜底后不会undefined) [state.enteredSubResourceName]:{ ...currentSubResource, // 保留subResource层的原有内容,避免覆盖 [state.selectedResourceOption]: action.payload.value // 添加或更新新的键值对 } } } };
关键修复点说明
- 空值兜底
|| {}:当某个层级的对象不存在时,用空对象代替,确保扩展运算符能正常工作,彻底解决undefined报错问题。 - 逐层展开已有内容:从最外层到最内层,每一层都先展开原有对象的内容,再添加新的键值对,这样就能保留原有数据,不会出现覆盖。
- 动态键的正确取值:修正了动态键的取值方式,用
[state.selectedResource]代替错误的点语法,确保能正确访问到目标层级。
这样修改后,既能自动创建不存在的嵌套键,又能完整保留原有对象的内容,完美解决你的两个问题~
内容的提问来源于stack exchange,提问作者Dorra Hadrich
相关产品推荐
相关产品推荐

