如何使用useReducer在状态变更时更新数组内的单个对象
问题原因
- reducer处理
SET_QUIZ_STATE时返回值错误:直接返回map后的quizState数组会把整个根state替换为该数组,丢失根state下的其他字段,也没有保留quizState外层键,后续访问state.quizState自然为undefined。 - 状态合并语法错误:
{...quiz, payload}会将整个payload作为名为payload的属性塞入对象,不会合并payload的内部字段,需要改为{...quiz, ...payload}展开payload的字段。 - 字段名不匹配:dispatch的payload中使用的是
answers字段,但是初始state里定义的答案字段是answer,会导致数据存储错位。
修复方案
修正reducer逻辑
const appState = { // 其他根状态字段保留 quizState: [ {id:0, question_id: '', answer: [] }, {id:1, question_id: '', answer: [] }, {id:2, question_id: '', answer: [] }, {id:3, question_id: '', answer: [] }, {id:4, question_id: '', answer: [] }, ] } export const appReducer = (state = appState, action) => { const { type, payload } = action; switch (type) { case SET_QUIZ_STATE: // 返回完整根state,仅更新quizState字段 return { ...state, quizState: state.quizState.map((quiz) => quiz.id === payload.id ? ({...quiz, ...payload}) : quiz) } default: return state; }};
统一字段名(可选)
如果需要将答案存入初始定义的answer字段,调用setQuizState时调整字段名即可:
setQuizState({ id: 0, question_id: question.question_id, answer: [true, false] });
内容的提问来源于stack exchange,提问作者wolf
相关产品推荐
相关产品推荐

