Redux更新数组对象属性:concat替代slice无效且无报错问题求助
排查Redux Reducer中concat实现的问题
咱们一步步拆解你的代码问题,你的concat写法有两个关键错误导致状态更新不生效:
1. concat的用法逻辑错误
你当前的写法return state.concat([{...state[i], likes: state.likes +1}]);,会把修改后的对象直接追加到原数组末尾,而不是替换掉索引i位置的目标元素。
原来注释里的slice写法逻辑是对的:把原数组拆成[0, i)的前半段、修改后的元素、[i+1, end)的后半段,合并成新数组完成替换。但现在的concat写法完全偏离了这个替换逻辑,相当于给数组新增了一个元素,而非修改指定位置的内容。
2. 属性访问错误
你写的state.likes是错误的:state是数组,本身没有likes属性,应该访问目标元素的likes,也就是state[i].likes。这个错误会导致likes被设置为NaN(undefined + 1 = NaN),就算concat逻辑正确,状态也会出问题。
正确的concat实现方式
要实现和slice展开写法等价的效果,你需要用concat分别拼接前半段、修改后的元素、后半段:
function posts(state = [], action) { switch(action.type) { case 'INCREMENT_LIKES': const i = action.index; return state.slice(0, i) .concat({...state[i], likes: state[i].likes + 1}) .concat(state.slice(i + 1)); default: return state; } } export default posts;
为什么这样写可行?
state.slice(0, i):获取原数组中从开头到索引i之前的所有元素(不包含i).concat({...state[i], likes: state[i].likes + 1}):把修改后的对象拼接到前半段后面(concat可以接收单个元素作为参数,不需要包成数组).concat(state.slice(i + 1)):再把原数组中从索引i+1到末尾的元素拼接上来
这样最终得到的新数组,就和你注释里的slice展开写法效果完全一致:替换了索引i位置的元素,同时保持了Redux要求的状态不可变性。
内容的提问来源于stack exchange,提问作者Aessandro
相关产品推荐
相关产品推荐

