Why multiple calls to set state with the React useState hook don't work
Published: 2023-01-04 18:25:38

---
title: Why multiple calls to set state with the React useState hook don't work
published: true
date: 2023-01-04 00:00:00 UTC
tags: 
canonical_url: https://www.frontendundefined.com/posts/react-issues/react-usestate-hook-multiple-calls-not-working/
---

You are making multiple calls to setState from React's useState hook. Perhaps you want to add multiple items into an array that is in that state variable. But only one item is added! Here's a list component with the same problem.

```javascript
import { useEffect, useState } from 'react';

const List = () => {
    const [list, setList] = useState([]);

    useEffect(() => {
        setList([...list, 'Item 1']);
        setList([...list, 'Item 2']);
        setList([...list, 'Item 3']);
    }, []);

    return (
        <div>
            <h1>List</h1>
            {list.map((item, index) => (
                <p key={index}>{item}</p>
            ))}
        </div>
    )
}

export default List;
```

![A screenshot of the browser when the List component is rendered](https://www.frontendundefined.com/posts/react-issues/react-usestate-hook-multiple-calls-not-working/list-output-720w.jpeg "Only one item is being added to the list 😕")

## Why does this happen?

Like I've explained in [this post](https://www.frontendundefined.com/posts/react-issues/react-usestate-hook-not-updating-immediately/), calling setState does not update the state immediately. It only asks React to do it in the future. So in this case, `list` keeps referring to the default empty list since React hasn't re-rendered the component yet.

```js
const List = () => {
    ...
    useEffect(() => {
        setList([...list, 'Item 1']); // list = [], setList(['Item 1'])
        setList([...list, 'Item 2']); // list = [], setList(['Item 2'])
        setList([...list, 'Item 3']); // list = [], setList(['Item 3'])
    }, []);
    ...
}
```

## How to do multiple state updates in React?

Similar to the [solution in this post](https://www.frontendundefined.com/posts/react-issues/react-usestate-hook-not-updating-immediately/), you can manage the new value separately and pass it into setState at the end.

```javascript
const List = () => {
    ...
    useEffect(() => {
        const newList = [...list];
        newList.push('Item 1');
        newList.push('Item 2');
        newList.push('Item 3');
        setList(newList);
    }, []);
    ...
}
```

Notice that I am creating a new list with `const newList = [...list]` since React state changes have to be immutable. If you modify the existing list and pass it into `setList`, React will not update the state.

<!-- REF: Immutable state, working with array / object state -->

Alternatively, you can pass a function into setState. React will then call this function with the last value that was passed into setState and then use the value returned from it as the new value.

```javascript
const List = () => {
    ...
    useEffect(() => {
        setList(list => [...list, 'Item 1']); // list = [], setList(['Item 1'])
        setList(list => [...list, 'Item 2']); // list = ['Item 1'], setList(['Item 1', 'Item 2'])
        setList(list => [...list, 'Item 3']); // list = ['Item 1', 'Item 2'], setList(['Item 1', 'Item 2', 'Item 3'])
    }, []);
    ...
}
```