【问题标题】:Problem with using deeper nested data fetched from API使用从 API 获取的更深层次的嵌套数据的问题
【发布时间】:2019-05-09 19:05:37
【问题描述】:

当我尝试从 PokeAPI 获取一些数据时遇到问题。这是我的 PokemonCard 组件代码。

import React, { useEffect, useState } from "react";
import axios from "axios";

const PokemonCard = ({ pokemonID }) => {
  const [pokemon, setPokemon] = useState({});
  useEffect(() => {
    (async () => {
      const result = await axios.get(
        `http://pokeapi.co/api/v2/pokemon/${pokemonID + 1}`
      );
      setPokemon(result.data);
    })();

    // console.log(pokemon.weight)
  }, [pokemonID]);
  return (
    <div className="pokemon">
      {pokemon.sprites.front_default}
    </div>
  );
};

export default PokemonCard;

当我尝试访问以下数据时,一切正常:pokemon.weightpokemon.base_experience。但是当我尝试使用一些更深层次的嵌套变量时会出错。

pokemon.sprites.front_default 给我一个错误 TypeError:

无法读取未定义的属性“front_default”。

这是来自 API 的数据示例:

    "name": "bulbasaur",
    "order": 1,
    "species": {
        "name": "bulbasaur",
        "url": "https://pokeapi.co/api/v2/pokemon-species/1/"
    },
    "sprites": {
        "back_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/1.png",
        "back_female": null,
        "back_shiny": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/shiny/1.png",
        "back_shiny_female": null,
        "front_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png",
        "front_female": null,
        "front_shiny": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/1.png",
        "front_shiny_female": null
    },
    "stats": [        
        {
            "base_stat": 45,
            "effort": 0,
            "stat": {
                "name": "hp",
                "url": "https://pokeapi.co/api/v2/stat/1/"
            }
        }
    ],
    "types": [
        {
            "slot": 2,
            "type": {
                "name": "poison",
                "url": "https://pokeapi.co/api/v2/type/4/"
            }
        },
        {
            "slot": 1,
            "type": {
                "name": "grass",
                "url": "https://pokeapi.co/api/v2/type/12/"
            }
        }
    ],
    "weight": 69

PS。在每个子组件中对 API 进行大约 150 次单独调用是一种好习惯吗?或者我应该以某种方式通过一个电话来做到这一点?谢谢。

【问题讨论】:

    标签: javascript json reactjs axios


    【解决方案1】:

    您试图访问 pokemon 变量的未定义键中的键。请检查您实际渲染的更新行。

    {pokemon.sprites ? pokemon.sprites.front_default : ''}
    

    因为 Pokemon 在 api 获取数据之前是一个空对象,并且 更新状态,所以 pokemon.sprites 实际上是未定义的。

    import React, { useEffect, useState } from "react";
    import axios from "axios";
    
    const PokemonCard = ({ pokemonID }) => {
      const [pokemon, setPokemon] = useState({});
      useEffect(() => {
        (async () => {
          const result = await axios.get(
            `http://pokeapi.co/api/v2/pokemon/${pokemonID + 1}`
          );
          setPokemon(result.data);
        })();
    
        // console.log(pokemon.weight)
      }, [pokemonID]);
      return (
        <div className="pokemon">
          //this should work for you
          {pokemon.sprites ? pokemon.sprites.front_default : ''}
        </div>
      );
    };
    
    export default PokemonCard;
    

    【讨论】:

    • 是的,现在可以了,非常感谢您抽出宝贵时间。
    • @OskarNawara 不用担心。另外,不要忘记投票以表明上述解决方案可以达到目的。
    • 是的,但是:感谢您的反馈!声望低于 15 人的投票将被记录,但不会更改公开显示的帖子得分。 :(
    【解决方案2】:

    Optional chaining (?.) 中变得更容易

    pokemon.sprites?.front_default
    

    【讨论】:

      猜你喜欢
      • 2012-09-16
      • 2020-09-04
      • 2016-07-20
      • 2020-12-15
      • 2021-09-26
      • 2020-07-20
      • 2020-02-25
      • 2019-01-13
      • 1970-01-01
      相关资源
      最近更新 更多