React TypeScript 16.8 如何使 useEffect() 异步

Posted

技术标签:

【中文标题】React TypeScript 16.8 如何使 useEffect() 异步【英文标题】:React TypeScript 16.8 How to make useEffect() async 【发布时间】:2019-12-05 21:55:41 【问题描述】:

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

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

我得到的错误是

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

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

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

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

【问题讨论】:

【参考方案1】:

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

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

  genRandomKey();
, []);

更多:React Hooks Fetch Data

【讨论】:

【参考方案2】:

您可以像这样使用IIFE(自行执行的异步匿名函数):

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

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

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

【讨论】:

对于不知道它叫什么的人,它是IIFE(立即调用函数表达式),这里是MDN链接developer.mozilla.org/en-US/docs/Glossary/IIFE【参考方案3】:

为什么

useEffect 中使用异步函数会使回调函数返回 Promise 而不是 cleanup function。

解决方案

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

  foo();
, []);

或与IIFE

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

【讨论】:

这个答案的第一部分与托比亚斯的答案相同,第二部分与我的一个答案相同。【参考方案4】:

您可以使用提供useAsyncEffect 钩子的use-async-effect 包:

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

【讨论】:

以上是关于React TypeScript 16.8 如何使 useEffect() 异步的主要内容,如果未能解决你的问题,请参考以下文章

如何使用React 16.8 Hook适当获取项目索引?

如何使VS2015/2017的TypeScript支持React

英React v16.8发布

React(^16.8) 新增特性Hook

react16.8新特性

React 16.8发布:hooks终于来了!