Search code examples
reactjssetstatereact-componentreact-statereact-state-management

React setState for multi level state object


I'm trying to update my state object which contains multiple levels. See this example https://codesandbox.io/s/oq9kp9vy5y.

The problem is, that the values in the render method, does not update ... only the first one. Can I force an update or is there a better way?

Thanks Kasper


Solution

  • In your initial state, you have the kitchen object inside the calculatedUsage object. But in your setState call, you have the kitchen object outside of calculatedUsage.

    Also, when you are accessing the previous state within setState, it's best to use the functional version of setState, e.g.:

    componentDidMount() {
      this.setState(
        prevState => ({
          caclulatedUsage: {
            ...prevState.caclulatedUsage,
            bath: 12,
            kitchen: {
              ...prevState.caclulatedUsage.kitchen,
              stove: 14,
              fridge: 23,
              dishwasher: 34
            }
          }
        }),
        () => {
          console.log(this.state);
        }
      );
    }
    

    The reason for this is that setState can be asynchronous, which means that accessing this.state within it may not give you the value you expect. Using the functional version for transactional state changes guarantees consistent results.

    You may also want to take a look at the immer library. It makes updating deeply nested state much easier, by allowing you to do immutable updates with a mutable API. Here's a fork of your codesandbox example that uses immer: https://codesandbox.io/s/180p7p0o84