How to Wait for State to update in React

avatar

Borislav Hadzhiev

Last updated: Apr 30, 2022

banner

Photo from Unsplash

Wait for State to update in React #

Use the useEffect hook to wait for state to update in React. You can add the state variables you want to track to the hook's dependencies array and the function you pass to useEffect will run every time the state variables change.

App.js
import {useEffect, useState} from 'react'; const App = () => { const [count, setCount] = useState(0); useEffect(() => { console.log('useEffect ran. count is: ', count); }, [count]); // 👈️ add state variables you want to track return ( <div> <h2>Count: {count}</h2> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); }; export default App;

wait for state to update

The second parameter we passed to the useEffect hook is an array of dependencies.

The function we passed to the hook will get invoked any time one of the dependencies changes.

We added the count state variable to the hook's dependencies array, so any time count changes, the logic in our useEffect hook will re-run.

Anytime the button is clicked, the value of count changes and the function we passed to useEffect is invoked.

Add all of the state variables you want to track to the dependencies array of your useEffect hook.

Note that the hook is also invoked when the component mounts.

If you don't want to run the logic in your useEffect hook on the initial render, but only when the specific state variable changes, use a ref to return early on the initial render.

App.js
import {useEffect, useState, useRef} from 'react'; const App = () => { const [count, setCount] = useState(0); const isFirstRender = useRef(true); useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; // 👈️ return early if initial render } console.log('useEffect ran. count is: ', count); }, [count]); // 👈️ add state variables you want to track return ( <div> <h2>Count: {count}</h2> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); }; export default App;

We used a ref to exit early when the useEffect hook is run on mount.

wait for state to update skip initial render

Use this approach if you want to listen for state changes but need to skip the first render.

It should be noted that if you update a specific state variable in the useEffect hook and the variable is present in the hook's dependencies array, you would cause an infinite re-render loop.

Here is an example that demonstrates this issue.

App.js
import {useEffect, useState} from 'react'; const App = () => { const [count, setCount] = useState(0); useEffect(() => { console.log('useEffect ran. count is: ', count); setCount(count + 1); // 👈️ this causes infinite loop }, [count]); return ( <div> <h2>Count: {count}</h2> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); }; export default App;

The issue is that we have added the count state variable to the dependencies array of the useEffect hook, but we are also updating count in the hook.

Every time useEffect is run, the value for the count variable is changed, which re-runs the hook again because count is in its dependencies array.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.