Syberic Syberic - 5 months ago 140
Javascript Question

using ...spread, but redux still throws warning about state mutation

Redux throws Warning on dispatch:

Error: A state mutation was detected inside a dispatch, in the path:
roundHistory.2.tickets. Take a look at the reducer(s) handling the action {"type":"ARCHIVE_TICKETS","roundId":"575acd8373e574282ef18717","data":[{"_id":"575acd9573e574282ef18718","value":7,"user_id":"574c72156f355fc723ecdbbf","round_id":"575acd8373e574282ef18717","__v":0},{"_id":"575acd9573e574282ef18719","value":9,"user_id":"574c72156f355fc723ecdbbf","round_id":"575acd8373e574282ef18717","__v":0},{"_id":"575acd9573e574282ef1871a","value":8,"user_id":"574c72156f355fc723ecdbbf","round_id":"575acd8373e574282ef18717","__v":0},{"_id":"575acdac73e574282ef1871b","value":19,"user_id":"574c72156f355fc723ecdbbf","round_id":"575acd8373e574282ef18717","__v":0},{"_id":"575ad50c4c17851c12a3ec23","value":29,"user_id":"57522f0b1f08fc4257b9cbc6","round_id":"575acd8373e574282ef18717","__v":0},{"_id":"575ad50c4c17851c12a3ec24","value":28,"user_id":"57522f0b1f08fc4257b9cbc6","round_id":"575acd8373e574282ef18717","__v":0},{"_id":"575ad


The only reducer handling
ARCHIVE_TICKETS
action is this one:

case 'ARCHIVE_TICKETS' :
var archive = [...state.roundHistory];
for (var i in archive) {
if (archive[i]._id === action.roundId) {
archive[i].tickets = action.data;
}
}
return Object.assign({}, state, {
roundHistory: archive
});


How can it mutate the state if i use [...spread]?

Answer

The [...state.roundHistory] here is similar to [].concat(state.roundHistory). It's creating a new array, but the objects in the array are shared with state.roundHistory. If you want to mutate them you'll need to make copies of each item.

You can do this using Object.assign, similar to how what you did for your return value:

var archive = state.roundHistory.map(value => Object.assign({}, value));

Or (as you suggested in your own answer), you can use object-spread notation:

var archive = state.roundHistory.map(value => {...value});
Comments