You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Axios、useState/useEffect的React函数组件无限重渲染问题求解

问题原因

你的代码存在三处核心问题,共同引发了报错:

  • useEffect 回调直接使用await关键字但未标记为async,本身属于语法错误。即使要在useEffect中写异步逻辑,也不能直接将async函数作为useEffect的入参,需要在回调内部定义异步函数再执行。
  • 异步逻辑混乱:同时混用await和.then()两种异步处理方式,还调用了未定义的getQuote()函数,运行时会直接抛出未定义错误。
  • 触发无限重渲染的根因:你实际运行的代码中,请求数据+修改quote1状态的逻辑没有被正确包裹在依赖为空数组的useEffect中,而是直接写在了组件函数体顶层,导致每次组件渲染都会发起请求、修改状态触发重新渲染,形成死循环。

修复后的完整代码

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

import QuoteCard from './QuoteCard';

// 按照API返回的实际字段定义数据类型,符合TS规范
interface Quote {
  _id: string;
  quoteText: string;
  quoteAuthor: string;
  quoteGenre: string;
  __v: number;
}

const MainQuotes = () => {
  // 给state声明类型,初始值设为null
  const [quote1, setQuote1] = useState<Quote | null>(null);

  useEffect(() => {
    // 内部定义异步请求函数
    const fetchRandomQuote = async () => {
      try {
        const resp = await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random');
        setQuote1(resp.data.data[0]);
      } catch (err) {
        console.error('名言获取失败:', err);
      }
    };
    // 执行请求
    fetchRandomQuote();
  }, []); // 依赖为空数组,仅在组件首次挂载时执行一次

  // 增加加载状态,避免quote1为空时子组件接收异常props
  if (!quote1) return <div>加载中...</div>;

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

export default MainQuotes;

注意事项

  • 不要在组件函数顶层直接调用会修改state的方法,所有初始化数据请求都需要放在依赖为空数组的useEffect中,保证仅执行一次
  • async/await 和 .then() 两种异步处理方式不要混用,统一使用一种即可
  • TypeScript项目中需要给state、props声明明确的类型,避免隐式any类型报错

内容的提问来源于stack exchange,提问作者Jack_Lynch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 05:45:03