Search code examples
reactjssetstate

When changing one specific state setting, is it necessary to restate all the other ones?


Let's say, I have a state that looks as follows.

constructor(props) {
  super(props);

  this.state = {
    setting_a: "value-1",
    setting_b: "color-green"
  }
}

When I change the state of a specific setting (e.g. setting_a), I don't want other settings (e.g. setting_b) to disappear. So I also specify the other settings while changing the state. (which is easy using the spread operator ...state).

this.setState( {...this.state, setting_a: "value-2"});

I noticed though, that some tutorials restate them, and others only specify the changed key-values.

Things got just a little bit more complicated since the introduction of the Component#getDerivedStateFromProps method, ( since React 16.3 ).

static getDerivedStateFromProps(props, state) {
  const oldSetting = state.setting_a;
  const newSetting = props.setting_a;

  if (oldSetting !== newSetting) {
    // this is a very similar situation.
    return ({ ...state, state.setting_a: props.setting_a});
  }
  return null;
}

Again, in the above example, I add all previous settings (i.e. ...state), because I don't want the other settings to be removed.

In both these cases, the same question: do I need to specifically repeat values which are already in the state ? Or are the states always merged incrementally, without removing ?


Solution

  • You don't need to copy the state (using spread operator or any idea) when updating the state with setState. The setState method updates the required state only:

    this.setState( {setting_a: "value-2"});
    

    So, now you will still get:

    state = {
        setting_a: "value-2",
        setting_b: "color-green"
      }
    

    Similarly, it works like that when you return the object in getDerivedStateFromProps. The returned value is applied in the state without mutation.


    You only need to copy the state when you want to update the property of state. For eg.:

    // initial state
    this.state = {
      settings: {
        a: 'value-1',
        b: 'color-green'
      }
    }
    

    Now, we have a and b property in settings state. So now, if you wanted to update the a, then you'll need to copy the settings:

    this.setState((state) => ({settings: {...state.settings, a: 'value-2' } }))
    

    The preceding example is with settings object. You can think similar with array of state. You may just do a google search for how to update the array without mutation?