If you use redux, you probably merge objects a lot when updating the redux state, the redux documentation suggests the use of the spread operator as an alternative to Object.assign
In a debugging session, I realized that the spread operator, just like Object.assign
does not merge the deeply nested properties of objects as expected.
Take for example the code below
import { merge } from "lodash";
const obj = {'a': 1, 'b': 2, 'c': { 'd': 4, 'e': 5, 'f': 6 } }
const updatedObj = {'a': 1, 'b': 2, 'c': { 'd': 3, 'e': 4 }}
// key f got lost because it's not in updatedObj
console.log({...obj, ...updatedObj});
// Outputs { a: 1, b: 2, c: { d: 3, e: 4 } }
// The same goes for Object.assign
console.log(Object.assign({}, obj, updatedObj));
// Outputs { a: 1, b: 2, c: { d: 3, e: 4 } }
// using lodash's merge
console.log(merge({}, obj, updatedObj));
// Outputs { a: 1, b: 2, c: { d: 3, e: 4, f: 6 } }
Although in a well structured redux state update, cases like this might not occur often, but it’s worth knowing when updating the redux state and when debugging.
Check the documentation for lodash’s merge here. Also note that, merge, just like Object.assign mutates the first object passed to it. When using it with the redux state, pass an empty object as the first argument to prevent mutating your state.
// This is bad
const newState = merge(state, action.payload);
// This is good
const newState = merge({}, state, action.payload);
THANKS FOR READING!