user1189352 user1189352 - 9 days ago 10
Javascript Question

Redux pushing to a nested array without mutating the state

I have a state object that looks like this:

PlaylistDictionary: {
someId: {
pages: [] // trying to push something to this array here
},
someId2: {
pages: [] // trying to push something to this array here
}, etc
}


I'm trying to update the "pages" array but I keep getting an error saying I'm mutating the state.. which I don't understand because if I'm making a copy of the state object with Object.assign... how am i mutating the state? thank you for any help

case types.ADD_PAGE_TO_PLAYLIST: {
let playlistDictCopy = Object.assign({}, state.playlistDict );

if ( !playlistDictCopy[ action.playlistId ].hasOwnProperty('pages') ) {
playlistDictCopy[ action.playlistId ].pages = [];
}

playlistDictCopy[ action.playlistId ].pages.push( action.pageId );

return Object.assign( {}, state, { playlistDict: playlistDictCopy } );
}

Answer Source

You're making a shallow copy of the state object, you are not copying any of the property values at all, including the array itself, so you are mutating the array.

Your .push call changes the array, and since you haven't created a new array, that will affect all previously stored state objects as well.

You can do

playlistDictCopy[ action.playlistId ].pages = playlistDictCopy[ action.playlistId ].pages.concat([action.pageId]);

or

playlistDictCopy[ action.playlistId ].pages = [ ...playlistDictCopy[ action.playlistId ].pages, action.pageId]);

to create a new array instead.