React TypeScript 16.8 如何使 useEffect() 异步

Bil*_*ill 28 async-await typescript reactjs react-hooks

为什么不能useEffect()使用 async-await?

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

Run Code Online (Sandbox Code Playgroud)

我得到的错误是

“() => Promise”类型的参数不可分配给“EffectCallback”类型的参数。

类型 'Promise' 不可分配给类型 'void | (() => void | undefined)'。

类型 'Promise' 不可分配给类型 '() => void | 不明确的'。

类型 'Promise' 不匹配签名 '(): void | 未定义'.ts(2345)

Tob*_*ins 24

不建议将效果声明为异步函数。但是您可以在效果中调用异步函数,如下所示:

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

  genRandomKey();
}, []);
Run Code Online (Sandbox Code Playgroud)

更多信息:React Hooks 获取数据

  • 这样做要小心……await 之后的异步回调可能会在react 组件被卸载后返回,并且如果您在该场景中触摸任何组件状态,react 将崩溃并抛出一些令人讨厌的错误。每当您在 useEffect 等中执行异步操作时,您都应该在接触状态之前检查组件是否已卸载。 (3认同)

Dan*_*iel 8

您可以使用异步匿名函数,它会像这样执行自己:

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

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

    return () => {
        // Component unmount code.
    };
}, []);
Run Code Online (Sandbox Code Playgroud)

  • 对于那些不知道它叫什么的人来说,它是 IIFE(立即调用函数表达式),这里是 MDN 链接 https://developer.mozilla.org/en-US/docs/Glossary/IIFE (3认同)

Nik*_*kar 5

为什么

使用 async 函数useEffect使回调函数返回一个 Promise 而不是清理函数

解决方案

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

  foo();
}, []);
Run Code Online (Sandbox Code Playgroud)

或与IIFE

useEffect(() => {
  (async () => {
    await performPromise()
  })()
}, []);
Run Code Online (Sandbox Code Playgroud)