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

解决useEffect+axios触发Maximum Update Depth Exceeded错误问题

解决React useEffect无限更新(Maximum Update Depth Exceeded)问题

错误信息

Maximum Update Depth Exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render

问题场景

使用useEffect请求汇率接口时触发上述错误,模拟器出现白屏;改用本地示例数据直接设置状态时,代码可正常运行。接口密钥已替换为真实值,链接在浏览器测试可用(示例数据取自该接口)。

原始代码

const [data, setData] = useState()
const [rates, setRates] = useState()
const [baseCurrencies, setBases] = useState();
const [resultCurrencies, setResult] = useState();

useEffect(() => {
  const fetchData = async () => {
    const response = await axios.get('https://api.apilayer.com/exchangerates_data/latest?apikey={KEY IS HERE}&base=EUR')
    const data = response.data
    if(data){
      setData(data)
      setRates(data.rates)
      setBases(getSymbols(data))
      setResult(getSymbols(data))
    }
  }
  fetchData()
}, [])

解决方案

1. 稳定getSymbols函数

错误核心原因大概率是getSymbols每次调用返回新的引用(如数组/对象),或函数本身在组件每次渲染时被重新创建,导致状态更新后触发无限重渲染。

  • 若getSymbols不依赖组件内部状态/ props,直接移到组件外部:
// 组件外部定义,确保引用稳定
const getSymbols = (data) => {
  if (!data?.rates) return [];
  return Object.keys(data.rates);
};
  • 若必须在组件内部定义,用useCallback缓存函数引用:
import { useCallback } from 'react';

// 组件内部
const getSymbols = useCallback((data) => {
  if (!data?.rates) return [];
  return Object.keys(data.rates);
}, []); // 空依赖数组保证函数引用稳定

2. 优化状态初始化与更新

给状态设置合理初始值,避免undefined引发的意外渲染;同时减少重复计算:

// 给状态设置初始值
const [data, setData] = useState(null);
const [rates, setRates] = useState({});
const [baseCurrencies, setBases] = useState([]);
const [resultCurrencies, setResult] = useState([]);

useEffect(() => {
  const fetchData = async () => {
    try {
      const response = await axios.get('https://api.apilayer.com/exchangerates_data/latest?apikey={KEY IS HERE}&base=EUR');
      const fetchedData = response.data;
      if (fetchedData) {
        setData(fetchedData);
        setRates(fetchedData.rates);
        // 只计算一次货币符号,避免重复调用getSymbols
        const symbols = getSymbols(fetchedData);
        setBases(symbols);
        setResult(symbols);
      }
    } catch (err) {
      console.error('汇率数据请求失败:', err);
      // 可添加错误提示状态,避免白屏
    }
  };
  fetchData();
}, []); // 若getSymbols在组件内且用了useCallback,可添加getSymbols到依赖数组

3. 解决白屏问题

在组件渲染时增加加载/空状态判断,防止数据未返回时因访问data属性报错:

return (
  <div>
    {data ? (
      // 渲染正常内容
      <div>基础货币:{baseCurrencies.join(', ')}</div>
    ) : (
      <div>加载中...</div>
    )}
  </div>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 07:24:23