【问题标题】:Infinite Re-rendering of React Functional Component using Axios and useState/useEffect?使用 Axios 和 useState/useEffect 无限重新渲染 React 功能组件?
【发布时间】:2021-11-26 03:17:48
【问题描述】:

我正在尝试使用 Typescript 创建一个 React 功能组件,该组件将从 API 获取数据,然后将该数据发送到另一个组件,但是,我收到“错误:重新渲染过多。React 限制防止无限循环的渲染次数。”

请提供任何建议!

useEffect(() => {
    await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random').then((resp) => {
            setQuote1(resp.data.data[0]);
        });
    getQuote();
}, []);

Snippet of Code Causing Error

编辑: 这是发生错误的整个文件。

import React, { useEffect, useState } from 'react';
import { Row, Col, CardGroup } from 'reactstrap';
import axios from 'axios';

import QuoteCard from './QuoteCard';

const MainQuotes = () => {
    const [quote1, setQuote1] = useState();

    useEffect(() => {
        await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random').then((resp) => {
                setQuote1(resp.data.data[0]);
            });
        getQuote();
    }, []);

    return (
        <Row>
            <Col>
                <CardGroup>
                    <QuoteCard quoteData={quote1} />
                </CardGroup>
            </Col>
        </Row>
    );
};

export default MainQuotes;

【问题讨论】:

  • 这段代码看起来不错。 setQuote1 到底是做什么的?
  • 你确定有错误吗?
  • 同意@SuthanBala,发布 setQuote1
  • @LeshawnRice 我刚刚发布了整个文件
  • @Jack_Lynch 设置状态会导致重新渲染,这就是它循环的原因。如果您在 useEffect 函数中将 quote1 添加到依赖数组中,它应该可以按预期工作

标签: javascript reactjs typescript use-effect use-state


【解决方案1】:

根据 quote1 的类型(我假设它是一个字符串)更新为:

const [quote1, setQuote1] = useState('')

useEffect(() => {
  function fetchQuote() {
    await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random')
    .then((resp) => {
      setQuote1(resp.data.data[0]);
    });
  }  
  if (!quote1) {
    fetchQuote();
  }
}, []);

由于 API 的响应是随机引用,所以你必须根据 quote1 的值来处理它。这应该可行,因为 quote1 只会在组件挂载后更新(当值为空字符串时),并且下面的渲染不会更新状态,所以 useEffect 不会无限循环。

在编辑之前,我假设 axios 请求在 getQuote 函数内部。我已更新我的答案以反映您发布的代码。

如果 API 响应是静态的,因为依赖数组中的项目只有在从当前值更改时才会导致重新渲染,所以它只会在第一次状态更新后立即导致重新渲染。

【讨论】:

  • 不幸的是,这并没有解决它,仍然得到无限循环错误
  • @jack_lynch 将 axios 请求包装在一个名为 getQuote 的函数中,我误读了代码,以为是在那个 func 中,
  • @Jack_Lynch 现在检查我的答案。它应该按预期工作
【解决方案2】:

我们可以获取您的完整代码吗?看来问题出在你的状态钩子上,并弄清楚它到底在做什么。

我现在的猜测是您的状态挂钩“setQuote1”正在以一种导致重新渲染的方式被调用,然后会再次调用您的 useEffect()(因为 useEffect 在渲染周期结束时运行)和因此,再次调用您的 setQuote1 挂钩。这会无限期地重复。

useEffect() 允许依赖,并让您能够准确判断何时应该调用 useEffect()。

示例:useEffect(() { code here }, [WATCH SPECIFICALLY THIS AND RUN ON WHEN UPDATES])。

当你将依赖数组留空时,你告诉钩子在任何时候更新状态时运行。这不一定是坏事,但在某些情况下,您只希望 useEffect() 在特定状态更新时运行。

您的应用程序中的某些东西一定会触发您的 useEffect() 钩子在您不希望它运行时运行。

【讨论】:

  • 我刚刚在问题的编辑中发布了整个文件
  • Stark,您能否修改您的答案以解决发布的新代码?
猜你喜欢
  • 2020-01-06
  • 2022-06-18
  • 2021-09-14
  • 1970-01-01
  • 2022-01-12
  • 2020-11-02
  • 2021-02-17
  • 1970-01-01
  • 2021-02-28
相关资源
最近更新 更多