Loading

How to update the state based on the previous state

How to update the state based on the previous state

In react, we normally update a state variable differently in class and functional component. Because update syntax is different in these two types of components.

In class component:

// variable declaration
this.state = {
  count: 0
}

// update value
this.setState({
   count: this.state.count + 1
})

In functional component

// variable declaration
const [count, setCount] = useState(0);

// update value
setCount(count + 1);

But in this article, we are going to discuss only class component and the discussion topic is "How to update the state based on the previous state". If we follow the regular procedure we might get some issues in some scenarios. Let's create that scenario and try to solve as well.

So the first step is to create a button and on its onClick event call an increment method to increment count state value.

// create a button and a onClick event
<button onClick={() => this.increment()}>Increment</button>

// increment method
increment = () => {
    this.setState({
        count: this.state.count + 1
    }, () => {
       console.log('Update value:', this.state.count)
    })
}

Up to this point, the application will work properly. Because the above scenario is very simple. Let's try to increment the count variable five times on a single button click event.

// create a button and a onClick event
<button onClick={() => this.incrementCountFiveTimes()}>Increment</button>

// incrementCountFiveTimes method
incrementCountFiveTimes() {
    this.increment()
    this.increment()
    this.increment()
    this.increment()
    this.increment()
}

If we run the application we would see the increment() called five times and console log the updated count value five times. But if we see carefully, each time the updated count value is the same i.e. 1. And it is because for better performance react may group multiple set state calls into a single update and the updated value does not carry over between the different calls.

Solution:

So, in such a scenario the solution to this problem is whenever we need to update the state based on the previous state we would pass a function as an argument to the this.setState() instead of passing in an object. So, the update increment() would be like this:

increment = () => {
    this.setState((prevState) => ({
        count: prevState.count + 1
    }))
}

This will give us the actual result every time in the console log. Because here we are incrementing the count variable with the previous state instead of the current state.

Related Articles