Search code examples
javascriptreduxreact-reduxlodashmutation

Returning new unmutated state with Object.assign & lodashs _.merge function?


Just came across something I don't understand. It's about redux state + lodashs _.merge function.

This does not work:

  const newState = Object.assign({}, state);
  const merge = {
    active: {
      userId: nextUserId
    }
  };

  return _.merge(newState, merge);

Whereas this does work:

  const newState = Object.assign({}, state);
  const merge = {
    active: {
      userId: nextUserId
    }
  };

  return _.merge({}, newState, merge);

The difference is the last line:

  return _.merge(newState, merge);

vs. :

  return _.merge({}, newState, merge);

I don't seem to understand why this makes a difference here though? _.merge is mutative, so it's best to "mutate" a newly created object, and not state itself - but in the first case, I am creating a new Object with Object.assign and return this as the new state. I am never once mutating state. Or am I? What is the problem here?


Solution

  • Object.assign creates a shallow copy, so any property deeper than level 1 still reference to the original state,

    This does not work: ?

     return _.merge(newState, merge);
    

    The newState is the destination object where the properties from merge object will be copied recursively, and since newState still refers to original state so any mutation eventually mutates original state

    Whereas this does work:

      return _.merge({}, newState, merge);
    

    The {} is the destination object where the properties from newState and merge object will be copied recursively, and since {} does not refers to original state so any mutation eventually will not effect original state