尝试更新reducer中的状态后,我一直收到以下错误:
"错误:在路径中的调度内检测到状态突变:
quiz.questions.0.answer
。看一下处理器的减速器 交流..."
我很确定我没有改变原始状态,因为我正在使用object.assign但错误仍然存在。
我的减速机:
case types.UPDATE_QUIZ_ANSWER:
let newStateObject = Object.assign({}, state);
let currentQuestion = newStateObject.questions.find(x => x.id == parseInt(action.data.questionId));
currentQuestion.answer = action.data.answer;
return Object.assign({}, newStateObject);
我的状态对象:
{"questions":
[{"id":1,"questionText":"Camps is?","multipleChoiceOption1":
{"value":"1","label":"Great"},"multipleChoiceOption2":
{"value":"2","label":"Fun"},"multipleChoiceOption3":
{"value":"3","label":"Awesome"},"multipleChoiceOption4":
{"value":"4","label":"All of the above"},
"answer":"2"},
{"id":2,"questionText":"At Camps we will?","multipleChoiceOption1":
{"value":"1","label":"AAA"},"multipleChoiceOption2":
{"value":"2","label":"Adult Focused"},"multipleChoiceOption3":
{"value":"3","label":"CCC"},"multipleChoiceOption4":
{"value":"4","label":"All of the above"},
"answer":"3"}],
"results":
{"quizPass":false,"quizResults":[]}}"
答案 0 :(得分:2)
Spread运算符...
aka Object.assign
仅适用于第一级对象属性。
let newStateObject = Object.assign({}, state);
let currentQuestion = newStateObject.questions.find(x => x.id == parseInt(action.data.questionId));
currentQuestion.answer = <----- here is the mutation
您可以做的是在每个级别创建一个对象副本:
// make a copy of the array
let newQuestions = [...newStateObject.questions];
let questionIndex = newQuestions.findIndex(x => x.id == parseInt(action.data.questionId));
// update array and question
newQuestions[questionIndex] = {...newQuestions[questionIndex], answer: action.data.answer};
// return new result
return {...state, questions: newQuestions};
答案 1 :(得分:1)
此代码正在改变您的状态:
let currentQuestion = newStateObject.questions.find(x => x.id ==
parseInt(action.data.questionId));
currentQuestion.answer = action.data.answer;
Object.assign
没有进行深层克隆,而您的newStateObject
肯定与原始state
不一致,currentQuestion
正在从{questions
数组中提取1}} 与原始状态对象图中的相同。
您可能希望查看类似Immutable.js的内容,但请按照以下方式考虑:您想要更改的实际对象需要替换,其父级(引用它的对象/数组)等等也是如此直到你的州的顶部。如果您使用的是combineReducers
,则只需要担心该切片的顶部,因为combineReducers
完成了上面的工作。