React: How to use async await in useEffect hook

Posted on

useEffect hook first argument is supposed to be a function. The function could return nothing / undefined or a clean-up function.

Let's take a look at useEffect that return nothing / undefined

useEffect(() => {
callApi();

// no return statement is equivalent to `return undefined`
}, []);

The second example is useEffect that return a clean-up function

useEffect(() => {
callApi();

return () => {
// clean up function
};
}, []);

Based on that characteristic, we could not use async / await for the argument because it will return a promise not a function. So, this below won't work

useEffect(async () => {
await callApi();
}, []);

React will give you a nice warning if you do that

async await use effect

Solution

As proposed by the warning, we could create a async function and call it immediately

useEffect(() => {
const fetchData = async () => {
const result = await callApi();
// could call set state here e.g setResult(result)
}

fetchData();
}, []);

Alternative syntax using IIFE (Immediately Invoked Function Expression)

useEffect(() => {
(async () => {
const result = await callApi();
// could call set state here e.g setResult(result)
})();
}, []);

Alternative syntax using then statement

useEffect(() => {
callApi().then((result) => {
// could call set state here e.g setResult(result)
})
}, []);

Playground

Check the Console tab

Summary

useEffect first argument is supposed to be a function that return nothing / undefined or a clean-up function. It could not be a promise.