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

Redux Toolkit Reducer报错:Cannot read properties of undefined (reading 'optionOne')

Redux Reducer 调试修复方案

核心问题分析

  • 初始状态错误:initialState中allQuestion设为null,首次操作时会因无法调用push或访问属性抛出错误,需根据数据结构初始化为空数组或对象。
  • 数据结构不统一:代码中混用数组操作(state.allQuestion.push())和对象索引(state.allQuestion[qid]),导致逻辑混乱。
  • 错误属性访问:第二段代码中错误使用state.value,但实际状态结构是{allQuestion: ...},不存在value属性,直接引发报错。
  • Immer 代理特性:打印state显示Proxy是Redux Toolkit内置Immer的正常行为,使用current(state)查看真实数据是正确做法,并非bug。

修复后的代码示例

场景1:问题数据以对象形式存储(key为问题ID)

import { createSlice, current } from "@reduxjs/toolkit"; 
import { _saveQuestion, _saveQuestionAnswer } from '../_DATA';

const allQuestionSlice = createSlice({
    name: "allQuestion",
    // 初始化为空对象,适配按qid索引的结构
    initialState: {
        allQuestion: {}
    },
    reducers: {
        allQuestionData: (state, action) => {
            state.allQuestion = action.payload;
        },  
        addNewAnswer: (state, action) => {
            const { authedUser, qid, option } = action.payload;
            // 确保目标问题存在再执行操作
            if (state.allQuestion[qid]) {
                state.allQuestion[qid][option].votes.push(authedUser);
            }
        },
    },
    extraReducers: (builder) => {
        builder.addCase("addQuestion", (state, action) => {
            // 按ID将新问题存入对象
            state.allQuestion[action.payload.id] = action.payload;
        });
    },    
});

export const saveQuestion = (saveQuestionData) => async (dispatch) => {
    const data = await _saveQuestion(saveQuestionData);
    dispatch({ type: "addQuestion", payload: data });
};

export const saveQuestionAnswer = ({ authedUser, qid, answer }) => async (dispatch) => {
    await _saveQuestionAnswer({ authedUser, qid, answer });
    dispatch(addNewAnswer({ authedUser, qid, option: answer }));
};

export const { allQuestionData, addNewAnswer } = allQuestionSlice.actions;
export default allQuestionSlice.reducer;

场景2:问题数据以数组形式存储

仅需修改addNewAnswer和addQuestion逻辑:

reducers: {
    // ...其他reducer
    addNewAnswer: (state, action) => {
        const { authedUser, qid, option } = action.payload;
        const targetQuestion = state.allQuestion.find(q => q.id === qid);
        if (targetQuestion) {
            targetQuestion[option].votes.push(authedUser);
        }
    },
},
extraReducers: (builder) => {
    builder.addCase("addQuestion", (state, action) => {
        state.allQuestion.push(action.payload);
    });
},

关键注意事项

  • 初始状态必须与实际数据结构匹配,避免null导致的空指针错误。
  • Redux Toolkit允许直接修改state(Immer自动转换为不可变更新),无需手动展开对象/数组。
  • 异步操作中,确保API调用成功后再分发action,避免状态不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:30:56