Redux Toolkit无法更新二维数组内嵌套对象状态问题
问题根源
你的UPDATE_PREDICTIONS reducer 写法存在4个错误,导致状态无法更新:
- 直接给函数内的
state局部变量重新赋值:Immer 通过追踪 draft 对象的变更生成新状态,直接重赋值局部变量不会修改原始 draft 引用,变更不会被识别。 find拿到匹配赛事对象后,直接给game局部变量重赋值:find返回的是对象引用,你给game变量赋新值只是修改了局部变量的指向,不会改动原数组里存储的赛事对象。- 没有完整遍历二维数组:你的state是按比赛轮次嵌套的二维数组,你只遍历了
state[0]也就是第一轮的赛事,其他轮次的匹配项根本不会被查到。同时map回调没有返回值,最终你赋值给state的是全为undefined的无效数组。 - 整体替换对象会丢失字段:你的payload只携带了要更新的字段名和分数,直接替换整个赛事对象会把队名、比赛时间、matchId等原有字段全部覆盖丢失。
修复方案
直接在遍历中修改匹配到的draft对象即可,Immer会自动追踪变更生成不可变状态,不需要手动map返回新数组:
import { createSlice } from "@reduxjs/toolkit"; export const predictFormSlice = createSlice({ name: "predictForm", initialState: [], reducers: { SAVE_FIXTURES: (state, action) => { state.push(action.payload); }, UPDATE_PREDICTIONS: (state, action) => { const { matchId, score, team } = action.payload; // 遍历所有比赛轮次 for (const roundFixtures of state) { // 查找当前轮次中匹配id的赛事 const targetMatch = roundFixtures.find(game => game.matchId === matchId); if (targetMatch) { // 动态更新对应比分字段 targetMatch[team] = score; // 可选:同步更新拼接的score展示字段 targetMatch.score = `${targetMatch.homeTeamScore ?? 'null'} - ${targetMatch.awayTeamScore ?? 'null'}`; // 匹配到后终止遍历 break; } } }, }, }); export const { SAVE_FIXTURES, UPDATE_PREDICTIONS } = predictFormSlice.actions; export default predictFormSlice.reducer;
注意点
- 移除了不必要的
current导入,原代码中没有用到这个API。 - 去掉了冗余的
any类型标注,如果你用TS可以自己补充对应赛事的接口类型,获得更好的类型提示。 - 不要在Immer reducer中给
state变量直接重新赋值,要么直接修改state的属性/内部嵌套元素,要么return一个新值作为新状态。
内容的提问来源于stack exchange,提问作者artworkjpm
相关产品推荐
相关产品推荐

