You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么Redux reducer未返回新数组时,绑定的React组件仍会触发重渲染?

问题原因解析

你遇到的现象是两个隐含逻辑共同作用的结果,和Redux的不可变原则、useSelector的默认比对逻辑有关:

  • 首先你在reducer中返回了新的外层state对象:你通过Object.assign({}, state, { appInfos })创建了一个和原state结构一致的新对象,虽然appInfos数组还是原引用,但整个appInfos reducer返回的state已经是新的引用,对应store中的state.appInfos值的引用发生了变化。
  • 其次你的mapStateToProps函数每次执行都会返回一个全新的对象{app: state.appInfos},而useSelector默认采用**严格相等(===)**比对前后两次返回值,两次返回的是不同引用的对象,所以useSelector会判定值发生了变化,触发组件重新渲染。

另外你直接修改原state中appInfos[0].name的操作是违反Redux不可变原则的错误写法,这次能看到渲染结果只是巧合:因为你已经提前修改了原数组内对象的属性值,组件重新渲染时读取到的就是修改后的值。但这种写法会带来很多隐性bug,比如其他依赖appInfos数组引用、或者依赖数组内对象引用的组件,会因为引用没有变化,出现该更新却不更新的问题。

正确写法参考

严格遵循不可变原则修改state,每次修改都要创建新的数组和变更的元素对象:

case 'SET_APP_NAME':
  return {
    ...state,
    appInfos: [
      // 只修改第一个元素,创建新的对象
      {...state.appInfos[0], name: action.name},
      // 剩余元素复用原引用
      ...state.appInfos.slice(1)
    ]
  }

如果要避免mapStateToProps每次返回新对象导致的不必要渲染,可以给useSelector传入第二个参数shallowEqual开启浅比较:

import { shallowEqual, useSelector } from 'react-redux'

const { app } = useSelector(mapStateToProps, shallowEqual)

内容的提问来源于stack exchange,提问作者labixiaoying

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 14:42:03