2017-09-07 2 views
0

ich folgende Fehler halten Staat Minderer zu ändern, nachdem er versuchte Zustand in meinem Minderer geworfen bekommen zu aktualisieren:Kann nicht herausfinden, wie, ohne dass eine Mutation

"Error: A state mutation was detected inside a dispatch, in the path: quiz.questions.0.answer . Take a look at the reducer(s) handling the ac..."

Ich bin mir ziemlich sicher, dass ich mutiert bin nicht der ursprüngliche Zustand, wie ich benutze object.assign noch der Fehler besteht.

Mein Minderer:

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); 

Mein Zustand Objekt:

{"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":[]}}" 

Antwort

2

Spread-Operator ... aka Object.assign funktioniert nur auf der ersten Ebene der Objekteigenschaften.

let newStateObject = Object.assign({}, state); 
let currentQuestion = newStateObject.questions.find(x => x.id == parseInt(action.data.questionId)); 
currentQuestion.answer = <----- here is the mutation 

Was Sie tun können, ist eine Kopie des Objekts auf jeder Ebene zu erstellen:

// 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

Dieser Code Ihr Zustand mutiert:

let currentQuestion = newStateObject.questions.find(x => x.id == 
    parseInt(action.data.questionId)); 
currentQuestion.answer = action.data.answer; 

Object.assign nicht tief Klon so, während newStateObject ist sicherlich nicht das gleiche wie Ihre ursprüngliche state, die currentQuestion Sie ziehen aus dem Array von questionsist das gleiche wie in der ursprünglichen Zustand Objektgraph.

Vielleicht möchten Sie in etwas wie Immutable.js suchen, aber denken Sie darüber nach: Das tatsächliche Objekt, das Sie ändern möchten, muss ersetzt werden, ebenso wie seine Eltern (das Objekt/Array, das es verweist) und so bis an die Spitze deines Staates. Wenn Sie combineReducers verwenden, müssen Sie nur über die Oberseite Scheibe seit combineReducers die Arbeit darüber kümmern.

+0

Ich bin in der Tat kombinieren reduders verwenden, haben aber Fälle sowohl für Frage und Zustandsänderungen in der gleichen Minderer führen wie sie beide mit Aktionen umgehen, die in meiner Quiz-Komponente generiert werden, aber diese sollten vielleicht durch separate Reduzierungen behandelt werden? Danke für den Vorschlag auf immutable.js, schaue es jetzt an –

Verwandte Themen