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

使用Promise.all与useState触发无限循环的问题及解决方法

修复useState与Promise.all结合导致的无限循环问题

我用Promise.all获取一组URL数据的功能正常,但调用setLocationResidents(results)更新状态时触发了无限循环,该如何修复?

原代码:

const residentsUrl = [
'https://rickandmortyapi.com/api/character/10', 'https://rickandmortyapi.com/api/character/81', 'https://rickandmortyapi.com/api/character/208', 'https://rickandmortyapi.com/api/character/226', 'https://rickandmortyapi.com/api/character/340', 'https://rickandmortyapi.com/api/character/362', 'https://rickandmortyapi.com/api/character/375', 'https://rickandmortyapi.com/api/character/382', 'https://rickandmortyapi.com/api/character/395'
]

const [locationResidents, setLocationResidents] = useState([])

useEffect(() => {
  async function fetchAll() {
    const results = await Promise.all(
      residentsUrl?.map((url) => fetch(url).then((r) => r.json()))
    );
    console.log("results", results);
    setLocationResidents(results);
  }
  fetchAll();
}, [residentsUrl, locationResidents]);

 <div>
      {locationResidents
        ?.map((location) => (
          <div>{location.name}</div>
        ))}
 </div>

问题原因

你的useEffect依赖数组中包含了locationResidents状态,每次调用setLocationResidents都会更新这个状态,触发useEffect重新执行,进而再次调用setLocationResidents,形成无限循环。

修复方案

直接从useEffect的依赖数组中移除locationResidents即可,因为这个状态是useEffect内部更新的,不需要作为依赖项。

修改后的代码

const residentsUrl = [
'https://rickandmortyapi.com/api/character/10', 'https://rickandmortyapi.com/api/character/81', 'https://rickandmortyapi.com/api/character/208', 'https://rickandmortyapi.com/api/character/226', 'https://rickandmortyapi.com/api/character/340', 'https://rickandmortyapi.com/api/character/362', 'https://rickandmortyapi.com/api/character/375', 'https://rickandmortyapi.com/api/character/382', 'https://rickandmortyapi.com/api/character/395'
]

const [locationResidents, setLocationResidents] = useState([])

useEffect(() => {
  async function fetchAll() {
    const results = await Promise.all(
      residentsUrl?.map((url) => fetch(url).then((r) => r.json()))
    );
    console.log("results", results);
    setLocationResidents(results);
  }
  fetchAll();
}, [residentsUrl]); // 移除locationResidents依赖

 <div>
      {locationResidents
        ?.map((location) => (
          <div>{location.name}</div>
        ))}
 </div>

额外优化(若URL数组动态变化)

如果residentsUrl是动态生成的(比如从props传入或其他状态计算而来),建议用useMemo缓存数组引用,避免因数组引用变化导致useEffect频繁触发:

import { useMemo } from 'react';

// 缓存动态生成的URL数组
const memoizedResidentsUrl = useMemo(() => {
  // 这里写动态生成数组的逻辑,比如处理props数据
  return [/* 生成的URL数组 */];
}, [/* 依赖项:比如props中用于生成数组的值 */]);

// useEffect依赖缓存后的数组
useEffect(() => {
  async function fetchAll() {
    const results = await Promise.all(
      memoizedResidentsUrl?.map((url) => fetch(url).then((r) => r.json()))
    );
    setLocationResidents(results);
  }
  fetchAll();
}, [memoizedResidentsUrl]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:09:14