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

React Native从AsyncStorage取两值作为Fetch参数时遇无限更新报错

解决React中「Maximum update depth exceeded」无限循环错误

错误原因分析

你遇到的无限循环问题,核心在于第二个useEffect的依赖数组包含了data:

  1. 当city或code更新时,触发effect执行fetch请求
  2. 请求完成后调用setData(data)更新状态,data的变化会再次触发这个effect
  3. 如果接口返回的data是空数组(或者data.length始终为0),就会重复进入if (data.length == 0)的判断,无限发起请求

修复方案及优化代码

下面是调整后的代码,从根源解决循环问题,同时优化异步逻辑:

import { useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';

const YourComponent = () => {
  const [data, setData] = useState([]);
  const [code, setCode] = useState('');
  const [city, setCity] = useState('');
  const [loading, setLoading] = useState(true);
  // 新增标记:记录是否已发起过请求,避免重复触发
  const [isFetched, setIsFetched] = useState(false);

  // 从AsyncStorage获取城市和编码
  useEffect(() => {
    const fetchStorageData = async () => {
      try {
        // 用Promise.all同时获取两个值,提升异步效率
        const [cityVal, codeVal] = await Promise.all([
          AsyncStorage.getItem('city'),
          AsyncStorage.getItem('code')
        ]);
        setCity(cityVal || '');
        setCode(codeVal || '');
      } catch (error) {
        console.error('获取存储数据失败:', error);
        setLoading(false);
      }
    };
    fetchStorageData();
  }, []);

  // 根据城市和编码发起接口请求
  useEffect(() => {
    // 仅当城市、编码都存在,且未发起过请求、处于加载状态时才执行
    if (city && code && !isFetched && loading) {
      const fetchApiData = async () => {
        try {
          const response = await fetch(`apiurlhere/${city}/${code}`);
          const resData = await response.json();
          setData(resData);
        } catch (error) {
          console.error('接口请求失败:', error);
        } finally {
          // 无论请求成败,都标记为已请求并结束加载
          setLoading(false);
          setIsFetched(true);
        }
      };
      fetchApiData();
    } else if (!city || !code) {
      // 若缺少必要参数,直接结束加载
      setLoading(false);
    }
  }, [city, code, loading, isFetched]);

  // 后续渲染逻辑...
  return (
    // 你的组件内容
  );
};

export default YourComponent;

关键修改说明

  • 移除data作为依赖:避免setData触发的状态更新重复调用effect
  • 新增isFetched标记:确保接口仅请求一次,彻底杜绝循环
  • 参数有效性判断:只有当city和code都不为空时才发起请求,避免无效URL
  • 异步逻辑优化:用Promise.all同时获取两个存储值,减少异步等待时间
  • 状态兜底处理:无论请求成败都更新loading和isFetched,避免组件一直处于加载状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:05:15