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

修改Redux Store后组件未刷新问题排查:修改JSON文件数据后connect函数触发但组件未重建

问题排查:Redux状态更新但组件未重新渲染

你完全找对了方向——就是不可变性的问题导致组件没重新渲染!

咱们来看你的reducer代码里的关键问题:

let DELETE_C_newChordOrder = state.mesures[action.mesure].chordOrder
DELETE_C_newChordOrder.splice(action.index, 1)

这里DELETE_C_newChordOrder只是原数组的引用,并没有创建新数组。而splice是直接修改原数组的方法,哪怕你后面用展开运算符拷贝了外层的mesures和对应小节对象,但chordOrder还是原来的那个数组引用。

Redux判断状态是否变化的核心是对比引用:如果新旧状态里的某个值引用没变化,它就会认为这部分状态没更新,自然不会触发组件的重新渲染。

修复方案有两种,选你顺手的就行:

方案1:先拷贝原数组再修改

先通过展开运算符创建原数组的副本,再对副本进行splice操作,这样就能保证返回的是新数组引用:

function songReduceur(state = initialState, action) {
  switch (action.type) {
    case CONSTANTS.DELETE_CHORD:
      // 先拷贝原数组,生成新引用
      const DELETE_C_newChordOrder = [...state.mesures[action.mesure].chordOrder]
      DELETE_C_newChordOrder.splice(action.index, 1)
      return {
        ...state,
        mesures:{
          ...state.mesures,
          [action.mesure]: {
            ...state.mesures[action.mesure],
            chordOrder: DELETE_C_newChordOrder
          }
        }
      }
    default:
      return state
  }
}
export default songReduceur

方案2:用filter生成新数组(更简洁的不可变操作)

filter方法天生会返回一个新数组,不需要手动拷贝,代码更简洁:

function songReduceur(state = initialState, action) {
  switch (action.type) {
    case CONSTANTS.DELETE_CHORD:
      return {
        ...state,
        mesures:{
          ...state.mesures,
          [action.mesure]: {
            ...state.mesures[action.mesure],
            // filter返回排除指定索引后的新数组
            chordOrder: state.mesures[action.mesure].chordOrder.filter((_, idx) => idx !== action.index)
          }
        }
      }
    default:
      return state
  }
}
export default songReduceur

记住一个核心原则:Redux的状态更新必须是不可变的——任何修改都要返回新的对象/数组引用,绝对不能直接修改原状态。这样connect才能正确检测到状态变化,触发组件重新渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 15:02:34