2

So first, the user object with a few properties (name, color, age) gets set up via SET_USER, and I would like to update the name property inside the user object via UPDATE_USER_NAME, yet when I do it with the following code down below with the nested looped in UPDATE_USER_NAME, the name property doesn't get updated.

What am I doing wrong? If I do something like user: {action.name, ...state.user}, the object user gets updated and works, but that just creates another new property from action.name rather than updating the current name inside the user object.

const DEFAULT_STATE = {
  user: {},
}

export default function(state = DEFAULT_STATE, action) {\
  switch(action.type) {
    case actionTypes.SET_USER:
      return {
        ...state,
        user: action.user,
      }

    case actionTypes.UPDATE_USER_NAME:
      return {
        ...state,
        user: {
          name: action.name,
          ...state.user,
        }
      }

    default:
      return state
  }
}
2
  • I find a nice way to do "merged" new object creation is to use the Object.assign api. Commented Oct 5, 2016 at 8:22
  • For example... user: Object.assign({}, state.user, { name: action.name }) Commented Oct 5, 2016 at 8:22

1 Answer 1

9

You just need to change the order of the spread a bit:

case actionTypes.UPDATE_USER_NAME:
      return {
        ...state,
        user: {
          ...state.user,
          name: action.name,
        }
      }

This will set user to the current state.user and then override name. the spread works like Object.assign (from left to right). This is because assigning the same keys in an object literal will be "last one wins".

Sign up to request clarification or add additional context in comments.

Comments