使用connect+mapStateToProps绑定Redux的React组件dispatch后不重渲染怎么办
问题排查与解决方案
核心根因
Redux 触发组件重渲染的前提是 mapStateToProps 返回的 props 发生了引用层面的变化,react-redux 内部默认做浅比较判断是否需要重渲染,你遇到的问题90%以上是因为违反了 Redux 不可变更新原则,返回了和原 state 相同引用的对象/数组。
具体修复步骤
修正 Reducer 返回值,保证引用更新
如果你的retrievedLData/retrievedRData是数组、对象这类引用类型,直接返回原引用会导致浅比较判定无变化,需要修改 Reducer 逻辑返回全新的引用:
同时要保证// RetrievedLDataReducer 示例,RetrievedRDataReducer 做相同修改 const RetrievedLDataReducer = (state = false, { type, payload }) => { switch (type) { case "UPDATE_RETRIEVED_DATAL": // 数组类型返回新数组 if (Array.isArray(payload)) return [...payload]; // 对象类型返回新对象,嵌套层级深可以用 structuredClone 或 immer 处理 if (typeof payload === 'object' && payload !== null) return {...payload}; // 基础类型直接返回 return payload; default: return state; } };dispatch时传入的payload不是直接修改后的原 state 引用,比如不要直接修改 store 中拿到的retrievedLeftTree再作为 payload 传入,要先拷贝再修改。优化组件绑定逻辑(可选,更适配函数式组件)
函数式组件更推荐用useSelector替代connect,可以自定义比较逻辑,更灵活可控:import { useSelector, shallowEqual } from 'react-redux'; function Foo1() { // 第二个参数可以自定义比较逻辑,需要深比较可以引入 lodash.isEqual const { retrievedLData, retrievedRData, loading } = useSelector(state => ({ retrievedLData: state.retrievedLData, retrievedRData: state.retrievedRData, loading: state.loading, }), shallowEqual); // 原有组件逻辑 } export default Foo1;普通函数调用 dispatch 逻辑无需修改
普通函数不需要通过connect绑定,只要传入正确的 store.dispatch 实例就可以正常触发 action,这块逻辑没有问题。废弃手动 subscribe 方案
手动调用store.subscribe会监听所有 store 变化,你没有做字段变化判断就触发请求才会导致性能问题,react-redux 自带的绑定逻辑已经自动做了变更检测,不需要自己实现订阅。
内容的提问来源于stack exchange,提问作者wowza_MAN
相关产品推荐
相关产品推荐

