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

使用Poke API获取初代宝可梦数据出现重复元素的解决咨询

解决Poke API获取初代宝可梦重复元素及map报错问题

问题分析

  1. 重复元素原因:

    • 当前代码在每个宝可梦请求返回后,就调用setAllPokemons往数组里添加单条数据,若useEffect被多次触发(比如依赖数组写了无意义的[0]、开发环境热重载),会导致多次发起全量请求,数组重复插入相同元素。
    • 并行异步请求的状态更新也可能因时机问题引发重复(虽函数式更新能缓解,但批量处理更稳妥)。
  2. 修改后报错原因:

    • 把setAllPokemons((urls) => [...urls, res.data])改成直接赋值setAllPokemons(res.data),会将allPokemons从数组覆盖成单个宝可梦对象,后续调用allPokemons.map时自然报错——对象没有map方法。

解决方案

方案一:批量请求后统一更新状态(推荐)

用Promise.all等待所有宝可梦请求完成,一次性把所有数据存入状态,避免多次更新导致的重复,同时确保useEffect只执行一次:

import React from "react";
import Card from "./Card";
import axios from "axios";

export default function Main() {
  const [allPokemons, setAllPokemons] = React.useState([]);

  React.useEffect(() => {
    axios.get("https://pokeapi.co/api/v2/pokemon?limit=151")
      .then((res) => {
        const pokeUrls = res.data.results.map((pokemon) => pokemon.url);
        // 批量发起所有请求,等待全部完成
        return Promise.all(pokeUrls.map(url => axios.get(url)));
      })
      .then((responses) => {
        // 提取所有响应的宝可梦数据
        const pokemonList = responses.map(res => res.data);
        setAllPokemons(pokemonList);
      })
      .catch(err => console.error("请求失败:", err));
  }, []); // 空依赖数组,确保组件仅挂载时执行一次请求

  const pokemonCard = allPokemons.map((pokemon) => (
    <Card
      name={pokemon.name}
      key={pokemon.id}
      id={pokemon.id}
      img={pokemon.sprites.front_default}
      type={pokemon.types[0].type.name}
    />
  ));

  return <div className="main-container">{pokemonCard}</div>;
}

方案二:逐步加载时添加去重逻辑

如果需要实现逐步加载(比如每加载一只就显示一只),可以在更新状态时检查是否已存在该宝可梦,避免重复:

// 替换原useEffect内的请求逻辑
axios.get("https://pokeapi.co/api/v2/pokemon?limit=151").then((res) => {
  const pokeUrls = res.data.results.map((pokemon) => pokemon.url);

  pokeUrls.map((url) =>
    axios.get(url).then((res) => {
      setAllPokemons((prevList) => {
        // 检查当前数组是否已有该id的宝可梦,没有才添加
        if (!prevList.some(poke => poke.id === res.data.id)) {
          return [...prevList, res.data];
        }
        return prevList; // 已存在则返回原数组
      });
    })
  );
});

同时记得把useEffect的依赖数组改成[],避免重复发起请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:40:39