Redux中目标数组未存在时,如何在Reducer中添加元素?
解决Redux Reducer中“not iterable”错误的方案
你遇到的这个错误核心原因很明确:当某个id是第一次被处理时,state.byId[action.payload.id]的值是undefined,而扩展运算符...只能作用于可迭代对象(比如数组),自然就会抛出“is not iterable”的错误。
只需要在Reducer里做一个简单的判断处理,就能解决这个问题——当目标数组不存在时,用空数组来替代undefined,这样扩展操作就能正常执行了。
修改后的Reducer代码
const initialState = { byId: {} }; function addReducer(state = initialState, action) { switch (action.type) { case "RECEIVE_DATA": return { ...state, byId: { ...state.byId, // 用||判断,不存在就用空数组兜底 [action.payload.id]: [ ...(state.byId[action.payload.id] || []), action.payload.data ] } }; default: return state; } } export default addReducer;
更严谨的写法(ES2020+)
如果你的项目支持ES2020及以上语法,推荐使用**空值合并运算符??**替代||,因为||会把空数组这类“假值”也替换成空数组,而??只会在值为null或undefined时才生效,逻辑更精准:
[action.payload.id]: [ ...(state.byId[action.payload.id] ?? []), action.payload.data ]
为什么不需要修改initialState?
你的initialState设计是合理的,因为无法预知未来会出现哪些id,提前在byId里预设所有可能的id显然不现实。我们只需要在每次处理RECEIVE_DATA action时,动态检查对应id的数组是否存在,不存在就用空数组兜底即可。
这样修改后,不管是第一次遇到某个id,还是后续添加数据,Reducer都能正常工作,不会再抛出错误啦。
内容的提问来源于stack exchange,提问作者devaent
相关产品推荐
相关产品推荐

