【问题标题】:Async/Await Function keeps triggering re-renderingAsync/Await 函数不断触发重新渲染
【发布时间】:2023-01-30 23:41:39
【问题描述】:

我在尝试使用 axios 从后端获取数据时遇到问题。该函数返回一个 Promise,每当我调用该函数时,我的组件都会不停地渲染。这是代码。

import { useState } from "react";
import Axios from "axios";

const DashBoard = () => {
  const [student, setStudent] = useState<{ [key: string]: string }[]>([]);
  const studentId = JSON.parse(localStorage.getItem("studentId") as string);
  const examResult: { [key: string]: string }[] = JSON.parse(
    localStorage.getItem("englishAnswers") as string
  );

  const getStudent = async () => {
    const { data } = await Axios.get(
      `http://localhost:3500/students/${studentId}`
    );
    setStudent(data);
  };
  getStudent(); //this line here keeps triggering re-render non stop;

【问题讨论】:

  • 你不应该在渲染阶段发起 HTTP 网络请求(除非你在服务器组件中这样做)。了解更多关于API requests in reactJs here

标签: reactjs typescript axios


【解决方案1】:

您需要将 getStudent() 调用包装在 useEffect 挂钩中。因为目前您正在调用 getStudent 函数每个render,当它触发一个setState方法时,这会导致无限渲染。

useEffect(() => {
  const getStudent = async () => {
    const { data } = await Axios.get(
      `http://localhost:3500/students/${studentId}`
    );
    setStudent(data);
  };

  getStudent();
}, []);

【讨论】:

    【解决方案2】:

    getStudent 函数在每次渲染时都会被调用:

    getStudent();
    

    由于该函数内的操作会更新状态,因此会触发重新渲染。所以每次渲染都会无限期地触发重新渲染。

    如果只是为了执行这个在第一次渲染,将它包装在一个带有空依赖数组的 useEffect 中:

    useEffect(() => {
      getStudent();
    }, []);
    

    如果 studentId 可能发生变化,而你想在它发生变化时重新调用它,请将其添加到依赖项数组中:

    useEffect(() => {
      getStudent();
    }, [studentId]);
    

    您可以更进一步,将函数本身放入useCallback

    const getStudent = useCallback(async () => {
      const { data } = await Axios.get(
        `http://localhost:3500/students/${studentId}`
      );
      setStudent(data);
    }, [studentId]);
    

    如果/当studentId发生变化时,这只会创建一个新的函数实例。然后函数本身可以是执行它的依赖项:

    useEffect(() => {
      getStudent();
    }, [getStudent]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 2022-01-25
      相关资源
      最近更新 更多