Photo by James Harrison on Unsplash

In class-based React components, we can pass a callback into the 2nd argument of setState to run code when a state is updated with setState .

With React hooks, we no longer have the setState method.

Instead, we use state updater functions created with the useState hook to update states.

This means we’ve to find new ways to run code after a state is updated.

In this article, we’ll look at how to run async code after a state is updated in function components created with React hooks.

useEffect Hook

The useEffect hook lets us commit side effects in our component code.

We can commit side effects in response to changes in one or more states.

To specify which state to watch, we pass an array of states we want to watch into the 2nd argument of useEffect .

Then in the useEffect callback we pass into the first argument, we can run code when the state in the 2nd argument changes since the callback in the first argument will be run when the state in the 2nd argument changes.

For instance, we can write:

import React, { useEffect, useState } from "react";
export default function App() {
const [loading, setLoading] = useState(false);
const [loading2, setLoading2] = useState(false);
  useEffect(() => {
setTimeout(() => setLoading(true), 1000);
}, []);
  useEffect(() => {
if (loading) {
setTimeout(() => setLoading2(true), 1000);
}, [loading]);
  return (

We have 2 states, loading and loading2 , which we updated inside the useEffect callbacks.

In the first useEffect callback, we call setTimeout with a callback that calls setLoading to set loading to true after 1000 milliseconds.

The empty array in the 2nd argument means that the useEffect callback only runs when the component is being mounted.

Next, we call useEffect again with a callback that gets the loading value.

In the callback, we check if loading is true ,

If it is, then we call setTimeout with a callback to call setLoading2 to set loading2 to true after 1000 milliseconds.

In the 2nd argument, we have an array that has the loading state.

This means whenever the loading state changes, the useEffect callback will run.

This means useEffect lets us run code on state updates.

In the JSX, we render the values of each state.

And we should see them become true one after the other.


We can run async code after state changes by calling the useEffect hook to watch the value of a state by passing the states we want to watch into the array in the 2nd argument of useEffect .

Then we can run code according to the value changes in the useEffect callback.

More content at

Run Async Code on Update of a State with React Hooks was originally published in JavaScript in Plain English on Medium, where people are continuing the conversation by highlighting and responding to this story.