我正在学习如何从Reaction中调用RESTAPI,并且对在异步函数中调用Reaction时会发生什么感到困惑.在下面的组件中,我们看到在fetchPlaces函数的第一行中,我们调用setIsFetching()状态为真.

import { useState, useEffect } from "react";
import Places from "./Places.jsx";
import Error from "./Error.jsx";
import { sortPlacesByDistance } from "../loc.js";
import { fetchAvailablePlaces } from "../http.js";

export default function AvailablePlaces({ onSelectPlace }) {
  const [isFetching, setIsFetching] = useState(false);
  const [availablePlaces, setAvailablePlaces] = useState([]);
  const [error, setError] = useState();

  useEffect(() => {

    async function fetchPlaces() {
      setIsFetching(true);
      try {
        const availablePlaces = await fetchAvailablePlaces();
          setAvailablePlaces(sortedPlaces);
          setIsFetching(false);
        });
      } catch (error) {
        setError({
          message:
            error.message || "Could not fetch places, please try again later.",
        });
        setIsFething(false);
      }
    }
    fetchPlaces();
  }, []);

  if (error) {
    return <Error title="An error occurred!" message={error.message} />;
  }

  return (
    <Places
      title="Available Places"
      places={availablePlaces}
      isLoading={isFetching}
      loadingText="Fetching place data..."
      fallbackText="No places available."
      onSelectPlace={onSelectPlace}
    />
  );
}

我这里的问题是,Reaction是否等待状态更新,直到整个函数完成?或者它会更新状态,因为它是一个异步函数,然后再次重新呈现组件?如果是,原因何在?

我猜我很困惑,因为在其他函数中,例如:

 function a() {
    setIsFetching(true)
    // .... a lot more logic is done below 
}

是否要等到a运行完成后才进行react ,以更新状态并重新呈现组件?为什么使用Async函数时,在函数运行之前更新状态?我认为它会等待整个函数执行,因为我们有AWait关键字

推荐答案

在更新之前,Reaction将一直等到您的代码将控制权交给JS事件循环.基本上:

async function fetchPlaces() {
  // no updates yet
  setIsFetching(true);
  // update is batched to be ran on the next rerender
  try {
    // by using `await` you are yielding control to the JS event loop.
    // code in this block will not run any more until `fetchAvailablePlaces` resolves.
    const availablePlaces = await fetchAvailablePlaces();
        // by here react will have updated the DOM
      setAvailablePlaces(sortedPlaces);
      // update is batched from the previous line
      setIsFetching(false);
      // this gets added to the batch
    });
  } catch (error) {
    setError({
      message:
        error.message || "Could not fetch places, please try again later.",
    });
    setIsFething(false);
  }
}
fetchPlaces();
}, []);

Reactjs相关问答推荐

如何将google地址lat收件箱设置为输入值?

使用Thattle和Use Effect setTimeout进行搜索有什么不同

我想删除NextJs中的X轴标签APEXCHARTS

在每页上应用字体-NextJS

为什么在页面重新加载时Location.State变得未定义?

如何在MUI x图表条形图上放置圆角?

在React中使用映射创建flex组件

如何动态地改变<; Select >;React和Tailwind元素?

如何在React组件中自动更新图表数据?

onClick 事件处理程序未应用于样式组件

尽管所有页面在 Reactjs 中都是公开的,但始终导航到特定页面

如何管理可重用无线电输入的 React 状态?

使用D3.js绘制和展示弦图的右下方象限

如何在next.js 13中仅在主页导航栏上隐藏组件?

Firebase Storage: 对象不存在图片上传路径错误

如何在不使用 Axios 的情况下将图像文件从 React.js 发送到 Spring Boot Rest API?

如何读取 null 的属性?

在 React 的父级中多次调用子级时从子级获取数据到父级

null 不是对象(判断RNSound.IsAndroid)

将 ref 转发到所有页面(路由组件)只是为了将其应用于
并具有跳过导航链接(按钮).有没有更好的办法?