Peter Kellner
Peter Kellner

Reputation: 15488

Getting error in react-redux reducer unexpected

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.

Upvotes: 0

Views: 69

Answers (1)

Oblosys
Oblosys

Reputation: 15106

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

Upvotes: 1

Related Questions