React与Redux中无法向已存有数据的fetchedSpendings状态数组添加元素的问题求助
问题原因分析
我一眼就看出核心问题出在你Reducer的PUSH_SPENDING分支里的push()方法使用错误:
Array.push()是会修改原数组的可变方法,直接违反了Redux状态不可变的核心原则;- 更关键的是,
push()的返回值是数组的新长度(数字类型),而非更新后的数组。这就导致你的fetchedSpendings状态被替换成了一个数字,后续组件调用props.Spending.map()时,自然会抛出“map is not a function”的错误——因为数字根本没有map方法。
你注释掉的代码之所以能“生效”,是因为它直接把原数组覆盖成了只包含新元素的数组,但这是替换而非追加,显然不符合你的需求。
解决方案
要在Redux中正确追加数组元素,必须创建一个全新的数组,绝对不能直接修改原状态数组。推荐两种常用的正确写法:
方法1:使用扩展运算符(最简洁直观)
修改Reducer中PUSH_SPENDING分支的返回逻辑:
case PUSH_SPENDING: return { ...state, fetchedSpendings: [...state.fetchedSpendings, action.payload] }
扩展运算符...会把原数组的所有元素展开,再把新元素action.payload追加到末尾,返回一个完全独立的新数组,完美符合Redux的不可变要求。
方法2:使用concat()方法
如果你更习惯用数组原生方法,concat()也是不错的选择(它不会修改原数组,而是返回拼接后的新数组):
case PUSH_SPENDING: return { ...state, fetchedSpendings: state.fetchedSpendings.concat(action.payload) }
额外提醒
Redux的核心原则之一是状态不可变,永远不要直接修改state里的对象或数组(比如push、pop、splice这类可变方法都要避免),必须返回新的引用。这样Redux才能准确检测到状态变化,触发组件的重新渲染。
你的actions.js代码看起来没有问题,只要Reducer修复后,就能正确实现追加新元素的功能了。
内容的提问来源于stack exchange,提问作者Cooler-cpu
相关产品推荐
相关产品推荐

