状态更新时React组件未重渲染,mapStateToProps执行正常求解决方案
问题:Redux状态更新后组件未重渲染,即使mapStateToProps已执行
我一眼就看出问题所在了——你虽然用Object.assign({}, state)克隆了外层的state对象,但数组是引用类型,newState.items依然指向原来的数组,你调用push的时候其实是在原地修改原数组,这属于Redux严格禁止的状态突变。Redux是通过浅比较来判断状态是否更新的,它会发现newState.items和之前的引用是同一个,所以认为状态没变化,组件自然不会触发重渲染。
咱们来一步步修正你的代码:
1. 先修复Reducer的初始化逻辑
你现在在reducer里判断!state.items才初始化数组,这种写法不够规范,直接把初始state设置为包含空数组的对象更稳妥:
const ItemsReducers = (state = { items: [] }, Action) => { console.log("inside the reducers", state); switch (Action.type) { case 'AddItem': // 返回全新的状态对象,items是新创建的数组 return { ...state, items: [...state.items, Action.payload] }; default: return state; } } export default ItemsReducers;
2. 为什么这样能解决问题?
- 用扩展运算符
...state克隆外层state对象 - 用
[...state.items, Action.payload]创建一个新数组,包含原数组的所有元素再加上新的payload,完全不会修改原数组的内容 - 这样Redux就能检测到
items的引用发生了变化,判定状态已更新,进而触发组件的重渲染
其他可行的写法(效果一致)
如果你习惯用concat,也可以这样写:
case 'AddItem': return { ...state, items: state.items.concat(Action.payload) };
concat方法本身会返回一个新数组,不会修改原数组,同样符合不可变更新的原则。
最后再提醒一下:Redux的核心原则就是状态不可变,任何时候都不要直接修改state里的对象或数组,必须返回全新的引用,这样才能保证状态更新的可预测性,也能让组件正常响应状态变化。
内容的提问来源于stack exchange,提问作者sarath
相关产品推荐
相关产品推荐

