[翻译]如何在React hooks useEffect中使用异步函数(Typescript/JS)?

乍一看,你可能会想到相似的事情,例如从远程API获取内容。javascript

const MyFunctionnalComponent: React.FC = props => {
  useEffect(async () => {
    await loadContent();
  }, []);
  
  return <div></div>;
 }
复制代码

会出现什么问题?

若是你使用Typescript, 则编译器会产生以下结果:html

Argument of type '() => Promise<void>' is not assignable to parameter of type 'EffectCallback'.
复制代码

让咱们经过异步函数的定义来看看为何会出现这个问题:java

A function that allows to use asynchronous instructions with the await keyword which will block the statement execution as long as the Promise after which the await keyword is doesn’t resolve…react

也就是说,容许将异步指令与await关键字一块儿使用的函数,只要不解决await关键字以后的Promise,它将阻止语句执行…typescript

没问题吧,好吧……可是等等……promise

This function will also return a Promise, no matter if you explicitly return something or not. In case you return data, it will be wrapped in the resolving content of the promise that the function will create and return automatically.安全

不管您是否明确返回某些内容,此函数都会返回一个Promise。万一你返回数据,它将包装在promise的解决内容中,自动建立并返回。bash

您开始发现问题了吗?没有? 让咱们阅读一下useEffect hook文档来获取更多信息。markdown

Often, effects create resources that need to be cleaned up before the component leaves the screen, such as a subscription or timer ID. To do this, the function passed to useEffect may return a clean-up function. For example, to create a subscription.app

一般,effects须要在组件离开屏幕以前清除建立的资源,例如订阅或计时器ID。为此,传递给useEffect的函数应该返回一个清理函数。

使用异步函数会使回调函数返回Promise而不是cleanup函数

这就是为何使用Typescript编译器会产生提示的缘由。这种模式在JS中也不起做用,由于react不会等待Promise

如何处理useEffect中的异步函数?

经过使用如下技巧,咱们能够在effects中使用异步函数:

const MyFunctionnalComponent: React.FC = props => {
  useEffect(() => {
    // Create an scoped async function in the hook
    async function anyNameFunction() {
      await loadContent();
    }
    // Execute the created function directly
    anyNameFunction();
  }, []);
return <div></div>;
};
复制代码

如今,你的代码是安全的,由于你什么也不返回,编译器也中止提醒。

你也可使用IIFE

const MyFunctionnalComponent: React.FC = props => {
  useEffect(() => {
    // Using an IIFE
    (async function anyNameFunction() {
      await loadContent();
    })();
  }, []);
  return <div></div>;
};
复制代码

原文地址:medium.com/javascript-…

相关文章
相关标签/搜索