React TypeScript 16.8 Как сделать useEffect() асинхронным

Почему useEffect() нельзя использовать асинхронное ожидание?

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

Ошибка, которую я получаю,

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)

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
46
0
34 503
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Не рекомендуется объявлять эффект как асинхронную функцию. Но вы можете вызывать асинхронные функции внутри эффекта, как показано ниже:

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

  genRandomKey();
}, []);

Подробнее здесь: React Hooks извлекает данные

Вы можете использовать пакет use-async-effect, который предоставляет крючок useAsyncEffect:

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

Вы можете использовать IIFE (асинхронную анонимную функцию, которая выполняется сама) следующим образом:

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

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

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

Для тех, кто не знает, как это называется, это IIFE (Immediately Invoked Function Expression) и вот ссылка MDN developer.mozilla.org/en-US/docs/Glossary/IIFE

Badmaash 17.09.2021 18:57

Почему

Использование асинхронной функции в useEffect заставляет функцию обратного вызова возвращать Promise вместо функция очистки.

Решение

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

  foo();
}, []);

ИЛИ с IIFE

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

Другие вопросы по теме