Why React setState/useState does not update immediately
Tags: react, abotwrotethis
Published: 2023-04-14 17:02:02

If you're new to React, you might have noticed that using `setState` or `useState` doesn't immediately update the state value. In this blog post, we'll dive into why this happens and how to work with it.

## Understanding React's state management

Before we dig into why `setState` and `useState` don't update immediately, we need to understand a bit about how React manages state.

In React, the component state is used to keep track of data that may change over time. We use `setState` or `useState` to modify the state values of a component.

When `setState` or `useState` is called, React schedules a re-render of the component with the updated state value. This is an asynchronous process, meaning that the component will not immediately update with the new state value.

React batching updates
---

One of the reasons why `setState` doesn't work immediately is that React batches updates. When you call `setState` multiple times in a row, React batches those updates and applies them in a single rendering.

For example, if you call `setState` four times in a row like this:

```jsx
this.setState({ count: 1 });
this.setState({ count: 2 });
this.setState({ count: 3 });
this.setState({ count: 4 });
```

React will only perform a single re-render with the final state `{ count: 4 }`.

The reason React does this is to optimize performance. By batching updates, React can minimize the number of re-renders it needs to perform.

Asynchronous state updates
---

Another reason why `setState` and `useState` don't work synchronously is that they are asynchronous.

When you call `setState` or `useState`, React doesn't immediately update the state value. Instead, it schedules a re-render of the component with the updated state value.

This means that the state value may not be updated by the time you try to access it. For example, consider the following code:

```jsx
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
```

If you run this code, you might expect the `console.log` statement to print the updated count. But because `setState` is asynchronous, the `console.log` statement will actually print the previous state value.

To work around this, you can use the `setState` function that takes a function as an argument. This function will be called with the previous state value, and can return a new state value based on the previous state.

```jsx
this.setState(prevState => {
  return { count: prevState.count + 1 };
});
```

This code will correctly update the state value and then log the new count.

Functional updates
---

Functional updates are another feature of `useState` that can cause confusion for those new to React's state management.

The `useState` hook lets you define state as an array with two elements. The first element is the state value, and the second element is a function that lets you update the state.

This function behaves similarly to `setState`, in that it schedules a re-render with the updated state value. But rather than accepting a new state value directly, this function takes an updater function.

```jsx
const [count, setCount] = useState(0);

setCount(prevCount => prevCount + 1);
```

This code will increment the count value by 1, just like `setState`.

Functional updates are especially useful when you need to update state values based on the previous state value. For example, consider a counter that increments by 2 instead of 1:

```jsx
setCount(prevCount => prevCount + 2);
```

Summary
---

In this blog post, we've covered the reasons why React's `setState` and `useState` functions don't update state immediately. We've seen how React batches updates to optimize performance, and how asynchronous updates can cause confusion for those new to React. We've also covered functional updates as a way to update state based on the previous state value.

By understanding how React manages state, you'll be better equipped to write efficient and predictable React components.