使用从API获取的更深层嵌套数据的问题

时间:2019-05-09 19:05:37

标签: javascript json reactjs axios

当我尝试从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.weight或pokemon.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次调用是一种好习惯吗?还是我应该以某种方式做到这一点?谢谢。

2 个答案:

答案 0 :(得分:0)

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

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

由于在api提取数据并更新到状态之前,Pokemon是一个空对象,因此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;

答案 1 :(得分:0)

Optional chaining (?.)

中变得更容易
pokemon.sprites?.front_default