0

I thought I had safely created a new state and returned with the following code inside my Redux reducer. Basically, I need to change one record inside my state.data array and return the new state. My expectation was that since newState is completely new that I was good.

After installing redux-immutable-state-invariant, I'm seeing that I still have a problem (code and error below).

    let newState = Object.assign({}, state);
    let newData = [];
    newState.data.map(function(rec){
        if (rec.id === sessionIdToUpdate) {
            rec.interestLevel = newInterestLevel;
            newData.push(rec);
        } else {
            newData.push(rec);
        }
    });
    newState.data = newData;
    return newState;

and the error...

A state mutation was detected inside a dispatch, in the path: `sessions.data.0.interestLevel`

If I comment out the line

rec.interestLevel = newInterestLevel;

the error goes away, but then so does the purpose of this reducer.

1 Answer 1

1

That's because Object.assign({}, state) creates a shallow copy, and data and all its rec objects are shared with the previous state object. If you assign to one of them, you mutate the old state.

Instead of mutating the rec, you can specify the new state declaratively with something like this:

const newState = {
  ...state,
  data: state.data.map((rec) => 
    rec.id === sessionIdToUpdate ? {...rec, interestLevel: newInterestLevel} : rec        
  )
};
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @oblosys and also thanks for the demo of returning a value from map sets that value to the record. I did not realize that (obviously).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.