How to go async with useEffect

Fernando Abolafio
3 min readMar 25, 2021

Execute asynchronous tasks with useEffect clean and safely

From calling an API to set a timeout delay, I am sure you already questioned how to do it properly when using the React hook useEffect . If that sounds still blurred, then this article is for you. If not, you may at least learn a different approach to get the job done or feel more confident while doing it.

I will present 3 ways of doing it safely and tidy. But first, I want to show what you should NOT do.

What you should NOT do ❌

Don’t do the async task directly in the useEffect, instead, ALWAYS wrap your async task into a function and only call it from the useEffect.

Here is an example of what you should NOT do:

useEffect(async () => {
await getData();

The code above would block the effect, which is no good. The function passed into useEffect must remain strictly synchronous.

Also, doing what this BAD example showed, would lead to a React error:

Effect callbacks are synchronous to prevent race conditions.

Alright, now we are safe to move on to the good practices ⬇️

1. Defining the async function inside the hook

If you intend to execute an asynchronous task, to get some data from an API for example, and update the loading state of your component, you need to define the function inside the hook and then call it:

useEffect(() => {   async function getData() {
const reponse = await myApi.getSomeGoodData()

The code above is 100% correct and it will get the job done for you most of the time. However, let’s say you want to reuse the getData function in multiple effects. Then, check number #2.

2. Defining the async function outside of the hook

If you plan to reuse the asynchronous function you defined, then a good idea is to define it in your functional component body, wrapped by the useCallback hook…



Fernando Abolafio

Fullstack Engineer — Modeling Revenue in code @GrowblocksHQ — Tweeting about Web Dev/React/Remix/NextJs — Software Architecture — Blockchain Tech/DAO/Decred