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

React无限重渲染问题求助:如何正确使用useEffect与fetch?

React调用PokeAPI的无限循环与渲染错误修复

问题原因分析

  1. 无限循环错误:PokemonList组件中直接在函数主体内调用setPokemonsArray,每次组件渲染都会触发状态更新,进而引发新一轮渲染,形成无限循环,导致React抛出Too many re-renders错误。
  2. 数据未加载时的map报错:App组件中pokemons初始状态设为空数组,此时pokemons.results为undefined,直接调用map会触发Cannot read properties of undefined (reading 'map')错误。

修复方案

1. 移除冗余局部状态,终止无限循环

PokemonList无需额外维护pokemonsArray状态,直接使用传入的pokemons props即可,消除状态更新引发的循环问题。

2. 处理异步数据加载的边界情况

  • 将App组件中pokemons的初始状态设为null,贴合API返回的对象结构(API返回包含results数组的对象,而非纯数组)。
  • 渲染列表前先判断pokemons.results是否存在,通过条件渲染避免空值调用map。

修改后的代码

App.js

import React from 'react'
import PokemonList from "./PokemonList";

function App() {
  // 初始状态设为null,匹配API返回的对象结构
  const [pokemons, setPokemons] = React.useState(null);

  React.useEffect(() => {
    console.log('fetch ran')
    fetch('https://pokeapi.co/api/v2/pokemon')
      .then(res => res.json())
      .then(data => {
        setPokemons(data);
      })
  }, [])

  return (
    <div>
      <PokemonList pokemons={pokemons} />
    </div>
  )
}

export default App;

PokemonList.js

import React from 'react'

export default function PokemonList({ pokemons }) {
  // 数据未加载时显示加载提示
  if (!pokemons?.results) {
    return <div>加载中...</div>
  }

  const pokemonsElements = pokemons.results.map((pokemon) => {
    return (
      <div key={pokemon.name}>
        <h3>{pokemon.name}</h3>
        <p>{pokemon.url}</p>
        <hr />
      </div>
    )
  })
  return (
    <div>
      {pokemonsElements}
    </div>
  )
}

额外说明

  • 使用pokemons?.results可选链操作符,安全访问嵌套属性,避免因pokemons为null或undefined导致的报错。
  • 增加加载状态渲染,提升用户体验的同时彻底规避数据未就绪时的渲染错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:35:17