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
相关产品推荐
相关产品推荐

