React TypeScript 16.8 How to make useEffect() async

31,107

Solution 1

Declaring the effect as async function is not recommended. But you can call async functions within the effect like following:

useEffect(() => {
  const genRandomKey = async () => {
    console.log(await ecc.randomKey())
  };

  genRandomKey();
}, []);

More here: React Hooks Fetch Data

Solution 2

You can use an IIFE (asynchronous anonymous function which executes itself) like so:

useEffect(() => {
    // Some synchronous code.

    (async () => {
        await doSomethingAsync();
    })();

    return () => {
        // Component unmount code.
    };
}, []);

Solution 3

Why

Using an async function in useEffect makes the callback function return a Promise instead of a cleanup function.

Solution

useEffect(() => {
  const foo = async () => {
    await performPromise()
  };

  foo();
}, []);

OR with IIFE

useEffect(() => {
  (async () => {
    await performPromise()
  })()
}, []);
Share:
31,107
Bill
Author by

Bill

Updated on July 09, 2022

Comments

  • Bill
    Bill almost 2 years

    Why can't useEffect() use async-await?

    const Home: React.FC = () => {
        
        useEffect(async () => {
            console.log(await ecc.randomKey())
        }, [])
        
        return (
        ...
    
    

    The error I get is

    Argument of type '() => Promise' is not assignable to parameter of type 'EffectCallback'.

    Type 'Promise' is not assignable to type 'void | (() => void | undefined)'.

    Type 'Promise' is not assignable to type '() => void | undefined'.

    Type 'Promise' provides no match for the signature '(): void | undefined'.ts(2345)

  • Badmaash
    Badmaash almost 3 years
    For those who don't know what it's called, it is IIFE (Immediately Invoked Function Expression) and here's the MDN link developer.mozilla.org/en-US/docs/Glossary/IIFE
  • Ryan Mann
    Ryan Mann about 2 years
    Be careful doing this.... async callbacks after await could return after a react component has been dismounted and if you touch any component state in that scenario react will crash and throw some nasty errors. Anytime you are doing async things in a useEffect etc you should be checking if the component has unmounted before touching state.
  • Liam Clark Gutiérrez
    Liam Clark Gutiérrez about 2 years
    I'm getting an IDE warning saying Promise returned from asyncMethod is ignored. Is this mechanism really safe?