useState bugs part I: Unexpected state update.
Tags: javascript, webdev, react, bug
Published: 2022-08-13 20:11:00

**So has it happened to you when the state updates in an unexpected way?** Keep this question in mind.

One of the most discouraging things in a developer's life is when he's just starting his project and boom! a bug steps in and here is what goes on in his mind:

"Oooh I think this is just a small bug and I will just fix it and continue my project and I'll be fine".

So, next thing he does , he tries and tries to fix the bug until he can't and he immediately looses motivation to work on that project and his day becomes a loss.

In this useState bugs series part I let's talk about the most common issue with useState and how to fix it.

So has it happened to you when the state updates in an unexpected way? comes again the question. If yes it's because many reactjs developers use useState without understanding how it works under the hood. Let's take this small app example:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t4peu1xhoyh27zx3ojos.png)

This is a very simple app we're going to be using for demonstration and what it does is just updating the state and the data in the h1 once I click on the **increase** button and also do so after 2 seconds when I click on the **increase asynchronously** button.

When I click on **increase**:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugfcjdy6hgk27x8b8ax5.png)

When I click on **increase asynchronously** , we wait two seconds and then see this:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eytax9bo482s6p7q2s1n.png)

So the buttons basically do the same thing within different time intervals.

So what I want to demonstrate here is the problem that may occur :

First note that the setTimeout function I used was to just simulate an asynchronous action like an http request where the state updates after it has resolved.

The problem occurs when I click **once** first on the **increase asynchronously button** and then click on the **increase** button imediately after **more than once like maybe twice or thrice**

What do you think will happen? So here's what happens:
_I click on the asynchronous button_:

![async button clicked](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h7tgqh7rdom2jv4f6igv.png)

**Of course nothing happens unless 2 seconds have passed by**

**BUT:**during that 2 seconds period I also click on the **increase** button exactly three times:
![3 times](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1x6avaqd8vlnc7egm1d2.png)

**And once** 2 seconds are over here's the result :
![2 seconds over](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/usplp0i06xamg6gr1j4v.png)

But why? We already had 3 as the value but the value changed back to 1, unexpected right?

So here is an explanation: When you click on the **increase asynchronously** and the javascript reaches the 'setNumber(number +1)' line it stores the current value and after two seconds are over it will add one to the stored value and in the example above the number was O so it added 1 and the result was 1.

This may produce unexpected behavior and may frustrate many developers once they don't recognize where the problem is.

So how to solve that :

**Solution**: _Use updating using a callback function in useState hook._

**Here's how:**

![solution](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3srez7sf2z6i7lfn4k76.png)

```
const increaseAsynchronously = () => {
    setTimeout(() => {
      setNumber(prevNumber => setNumber(prevNumber + 1));
    },2000)
  }
```
We provided the callback function and it takes one parameter which represents the current value of the state and that's why in that case it works perfectly fine . Let's repeat what we did before:

_I click on the asynchronous button_:

![sync button clicked](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xezv39jtevugmso50erz.png)
**Of course nothing happens unless 2 seconds have passed by**

**BUT:**during that 2 seconds period I also click on the **increase** button exactly three times:
![after 2 seconds](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcela3etfy0v4fwgr69q.png)

**And once** 2 seconds are over here's the result :
![bug fixed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1qxhbxj215tqa3zjuex.png)

So it works , you can see that now the result is the expected one.

**Thank you! Hope this helps someone.**

Let's discuss about this post in the discussion section and like for the algorithm.