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

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

会出现什么问题?

如果你使用Typescript, 则编译器会产生如下结果:

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

让我们通过异步函数的定义来看看为什么会出现这个问题:

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…

也就是说,允许将异步指令与await关键字一起使用的函数,只要不解决await关键字之后的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的解决内容中,自动创建并返回。

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

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.

通常,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>;

作者:Andréas Hanss

HookReact 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性,Hook 不会影响你对React概念得理解。 恰恰相反,Hook 为已知的 React 概念提供了更直接的 API:props, state,context,refs 以及生命周期。稍后我们将看到,Hook 还提供了一种更强大的方式来组合他们。从而使得函数式组件从无状态的变化为有状态的。 React 的类型包 @types/react 也同步把 React.SFC (St
方便,使代码更整洁。 允许以下 import { useAsyncEffect } from "@jeswr/use-async-effect" ; function MyComponent ( ) { useAsyncEffect ( async ( ) => { /* Effect goes here */ } , [ ] ) ; return /* JSX Output */ 相反,React带有useEffect异步函数调用的结构应如下: import { useEffect } from "react" ; function MyComponent ( ) { useEffect ( ( ) => { ( async ( ) => {
使用 use-async-effect: 异步副作用处理简化指南 use-async-effect:running: Asynchronous side effects, without the nonsense项目地址:https://gitcode.com/gh_mirrors/us/use-async-effect 1. 项目介绍 use-async-effect 是一个React Hoo...
使用React时,执行异步任务是常见的动作。 对于钩子,我们通常使用诸如const [loading, setLoading] = useState(false)来操纵我们的UI:显示一个加载指示器,一条错误消息,……这是在使您的工作更轻松一些与异步数据。 import React , { useState } from 'react' ; import axios from 'axios' import { useAsync } from 'react-hook-async' ; const Example = ( props ) 1. 问题叙述 在使用antd/G2图表更新的时候发现:在useEffect通过异步函数对图表渲染的data进行更新, 但是由于第一次更新后,数据是延迟更新的,所以好像数据并没有实时进行更新. 2. 代码分析 定义了一个heatmapData const [heatMapData, setHeatMapData] = useState...
最近一直在看ReactHook的相关知识,奈何没有实际的项目开发,于是乎上周新来的需求就决定用Hook来做,特此记录一下开发遇到的一个印象比较深刻的问题: 使用useEffectt进行性能优化时出现无限运行的情况: 出现这个问题的原因是因为useEffect的第二个参数数组的值为对象或者数组: React判断是否需要执行useEffect内代码是通过Object.is进行判断的,...
import { useCallback, useState } from "react"; import { useMountedRef } from "./index"; interface State<D> { error: Error | null; data: D | null; stat: "idle" | "loading" | "error" | "success"; const defaultInitialState: State<null&
Vue-router报错Argument of type ... is not assignable to parameter of type 'RouterOptions'的解决方案
这个问题说起来也奇怪,之前一直用得好好的,打包的时候突然router就报错了。报错信息很长,其最主要的就是这一段: Argument of type '{...(间一大段代码略过)}' is not assignable to parameter of type 'RouterOptions'. Types of property 'routes' are incompatible.