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

ReactJS子组件访问prop方法 PokeAPI开发props传undefined问题求解

问题根源

你代码的核心问题集中在异步逻辑处理、语法使用错误两个层面,具体如下:

  • 异步请求顺序错误:Axios请求属于异步操作,循环内发起的请求不会阻塞后续代码执行,你在循环里发起的单个宝可梦详情请求还没完成,就已经执行了setState把loading设为false,此时图片数组的对应位置还没被赋值,自然返回undefined。
  • setState异步特性误用:初始代码里每次循环都调用setState更新数组,不仅性能差,还可能因为state还没完成更新就取了旧值,导致后续请求参数错误。
  • map遍历参数使用错误:map的第一个参数是数组元素本身,不是索引。你写的pokemonNameListAPI.map((i) => {pokemonImgAPI[i]}里的i是宝可梦名称字符串,不是下标,当然拿不到对应的值。
  • state初始化不匹配:修改后的代码constructor里初始化的是pokemonNameAPI,但后续使用的是pokemonNameListAPI,两个变量名不一致,初始值永远为空。
修复方案

1. 统一state变量定义

不用拆分两个数组存储名称和图片,统一存储在一个数组里更不容易出错:

class GenerationPokemonStat extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pokemonList: [], // 存储每个宝可梦的完整信息
      pokemonLoading: true
    };
  }

2. 正确处理异步请求逻辑

用Promise.all等待所有单个宝可梦的请求完成后,再统一更新state:

searchAllPokemon = () => {
    this.setState({ pokemonLoading: true });
    let number = 10;
    Axios.get(`http://localhost:5000/getPokemonByGeneration/allPokemonGen/${number}`)
      .then(async res => {
        // 生成所有单个宝可梦的请求实例
        const pokemonPromises = res.data.results.map(item => 
          Axios.get(`http://localhost:5000/getPokemonByGeneration/one_pokemon_gen/${item.name}`)
        );
        // 等待所有请求全部完成
        const pokemonResponses = await Promise.all(pokemonPromises);
        // 整理需要的字段
        const pokemonList = pokemonResponses.map(res => ({
          name: res.data.name,
          img: res.data.sprites.front_default
        }));
        // 统一更新state
        this.setState({
          pokemonList,
          pokemonLoading: false
        });
      })
  }

3. 修正渲染遍历逻辑

直接遍历整理好的宝可梦列表即可:

render() {
    const { pokemonLoading, pokemonList } = this.state;
    return (
      <>
        <div>
          <button onClick={this.searchAllPokemon}>Search Pokemon</button>
          {pokemonLoading ? <h1 style={{ textAlign: 'center' }}>Loading...</h1> : (
            <div className="grid-container">
              {pokemonList.map((pokemon, index) => (
                <CardPokemon
                  key={index}
                  name={pokemon.name}
                  img={pokemon.img}
                />
              ))}
            </div>
          )}
        </div>
      </>
    );
  }
}

4. 简化子组件

直接传入对应属性,不用数组包装更易维护:

function CardPokemon({ name, img }) {
  return (
    <div className="Card">
      <div className="Card__img">
        <img src={img} alt={name} />
      </div>
      <div className="Card__name">
        {name}
      </div>
    </div>
  );
}

export default GenerationPokemonStat;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:36:04