BlockChange BlockChange - 3 months ago 66
React JSX Question

Redux: Add/remove from nested object/array, without mutating?

I thought

assign
was supposed to make a new object, that's why I did this in my reducer:

case types.ADD_ATTRIBUTE:
var newState = Object.assign({}, state)
newState.attributes[action.industry].push(action.attribute)
return Object.assign({}, state, newState);

case types.REMOVE_ATTRIBUTE:
var newState = Object.assign({}, state)
var removeIndex = newState.attributes[action.industry].indexOf(action.attribute)
newState.attributes[action.industry].splice(removeIndex, 1)
return Object.assign({}, state, newState);


However, when I do this, the component will not trigger an update (
componentWillReceiveProps
). It does receive the new props, but the
react-redux
internal
shouldComponentUpdate
does not detect changes.

What am I doing wrong here?

Answer

In case if you want to re-render object containing attributes[action.industry], you need to recreate this array same as you do with state.

case types.ADD_ATTRIBUTE:
  return {
    ...state,
    attributes: {
      ...state.attributes,
      [action.industry]: [...state.attributes[action.industry], action.attribute]
    }
  }

case types.REMOVE_ATTRIBUTE:
  const removeIndex = newState.attributes[action.industry].indexOf(action.attribute)
  return {
    ...state,
    attributes: {
      ...state.attributes,
      [action.industry]: [
          ...state.attributes[action.industry].slice(0, removeIndex), 
          ...state.attributes[action.industry].slice(removeIndex + 1)
        ]
      }
   }