为何在React Redux的mapStateToProps中不应使用toJS()?
toJS()? 首先得说,你现在没遇到重渲染问题完全正常,但这背后其实藏着容易被忽略的性能隐患,咱们慢慢说清楚:
toJS()会破坏React-Redux的浅比较优化
React-Redux判断组件是否需要重渲染的核心逻辑是对mapStateToProps返回的结果做浅比较。每次调用toJS(),都会把Immutable数据转换成一个全新的普通JS对象/数组——哪怕原Immutable数据根本没变化,浅比较都会认为“引用变了”,直接触发组件重渲染。现在没感觉,可能是因为你的组件层级浅、数据量小,但当应用规模变大,这种不必要的重渲染会不断累积,拖慢页面响应速度。浪费了Immutable.js的核心优势
Immutable.js的设计初衷是用结构共享来减少内存开销:当你更新Immutable数据时,它只会修改变化的节点,其他节点和原数据共享。但toJS()会完全复制整个数据结构,把所有节点都转成普通JS类型,等于直接放弃了结构共享带来的内存和性能收益,那用Immutable.js的意义就大打折扣了。Redux生态的推荐方向已经变化
现在Redux官方更推荐用Immer这类轻量库,或者直接用原生JS的不可变更新方式(比如扩展运算符...、数组的map/filter等返回新数组的方法)。Immutable.js有一定的学习成本,而且和React的适配不如原生不可变方式顺畅——比如JSX里直接用Immutable数据需要额外处理,而原生JS数据可以直接使用。
针对你当前情况的建议
如果你暂时不想换掉Immutable.js,可以这么优化:
- 尽量在组件内部保持Immutable数据的使用,用它自带的API(比如
get()、getIn())读取数据,不要转成普通对象 - 如果确实需要转普通对象,不要在
mapStateToProps里做,而是在组件内部用useMemo缓存转换结果,比如:
这样只有当原Immutable数据变化时,才会重新执行const data = useMemo(() => immutableData.toJS(), [immutableData])toJS(),避免不必要的转换和重渲染
内容的提问来源于stack exchange,提问作者Istvan Orban

