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

Redux实现点击切换CSS类时reducer异常,selectedAttr数组异常膨胀

问题根因

  • 核心问题出在reducer的逻辑错误,和redux-persist没有直接关系,redux-persist只是把你错误逻辑生成的异常数组持久化存储了,导致每次重启项目都加载错误的历史数据。

具体错误点:

  1. for循环逻辑错误:遍历已有属性数组时,只要当前遍历的条目和新值不属于同一属性组,就直接把新值push进数组,比如现有数组有3条和新值不同组的条目,点一次就会重复加3次新值,点击次数多了自然会膨胀到数千条。
  2. 重复合并旧值:处理完tmp数组后,返回新状态时你写了[...state.selectedAttr, ...tmp],等于把旧数组和处理过的新数组又拼接了一遍,重复添加的问题被进一步放大。
  3. 逻辑冗余:你的需求是「同一属性组(id中冒号前的部分)下只保留最新选中的值」,完全不需要循环,直接过滤即可。
  4. 如果之前遇到返回undefined的问题,额外检查根reducer的配置,确保挂载selectAttrReducer的key和mapStateToProps里取的key一致:
// 根reducer示例
const rootReducer = combineReducers({
  selectedAttr: selectAttrReducer // 此处key必须和mapStateToProps取的state.selectedAttr对应
})

修正后的reducer代码

const initialState = {
  selectedAttr: [],
}
 
export default function selectAttrReducer (state = initialState, action) {
  switch(action.type){
    case SELECT_ATTRIBUTES:
      // 取出新值的属性组id
      const newAttrGroup = action.payload.split(":")[0]
      // 先过滤掉同组的旧值,再加入新值即可
      const newSelectedAttr = [
        ...state.selectedAttr.filter(el => el.split(":")[0] !== newAttrGroup),
        action.payload
      ]
      return {
        ...state,
        selectedAttr: newSelectedAttr
      }
    default:
      return state    
  }
}

额外排查建议

如果修改后还能读到之前的数千条数据,清除一下浏览器本地存储(localStorage/sessionStorage,取决于你redux-persist配置的存储介质)即可,也可以在开发环境给redux-persist加版本控制,每次修改状态结构后自动清除旧的持久化数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:15:05