Redux实现点击切换CSS类时reducer异常,selectedAttr数组异常膨胀
问题根因
- 核心问题出在reducer的逻辑错误,和redux-persist没有直接关系,redux-persist只是把你错误逻辑生成的异常数组持久化存储了,导致每次重启项目都加载错误的历史数据。
具体错误点:
- for循环逻辑错误:遍历已有属性数组时,只要当前遍历的条目和新值不属于同一属性组,就直接把新值push进数组,比如现有数组有3条和新值不同组的条目,点一次就会重复加3次新值,点击次数多了自然会膨胀到数千条。
- 重复合并旧值:处理完tmp数组后,返回新状态时你写了
[...state.selectedAttr, ...tmp],等于把旧数组和处理过的新数组又拼接了一遍,重复添加的问题被进一步放大。 - 逻辑冗余:你的需求是「同一属性组(id中冒号前的部分)下只保留最新选中的值」,完全不需要循环,直接过滤即可。
- 如果之前遇到返回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
相关产品推荐
相关产品推荐

