TypeError:无法使用React读取undefined的属性

问题描述 投票:0回答:4

我是React的新手,我正在用PokeAPI做一个小应用程序。我有一个名为PokemonDetail的组件,其中我想显示一个小精灵的细节,但该应用程序会抛出下一个错误

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

我的组件看起来像这样:

import React from "react";

const PokemonDetail = ({ pokemon }) => {
  return (
    <div>
      <div className="text-center">{pokemon.name}</div>
      <img src={pokemon.sprites.front_default} alt={pokemon.name} />
      {pokemon.id}
    </div>
  );
};

export default PokemonDetail;

口袋妖怪细节接收口袋妖怪道具的App组件看起来像这样:

import React from "react";
import PokeAPI from "../apis/PokeAPI";
import SearchBar from "./SearchBar";
import PokemonDetail from "./PokemonDetail";

class App extends React.Component {
  state = { pokemon: '' };

  onTermSubmit = async term => {
    try {
      const response = await PokeAPI.get(`pokemon/${term}`);
      this.setState({ pokemon: response.data });
      console.log(response);
    } catch (error) {
      console.log("No existe");
    }
  };

  render() {
    return (
      <div className="container">
        <div className="row mt-3">
          <div className="col">
            <SearchBar onFormSubmit={this.onTermSubmit} />
          </div>
        </div>
        <div className="row mt-3">
          <div className="col-9" />
          <div className="col-3">
            <PokemonDetail pokemon={this.state.pokemon} />
          </div>
        </div>
      </div>
    );
  }
}

export default App;

我不明白为什么它会抛出这个错误,因为只抛出它与json的这个和其他属性。随着name属性的工作,并等到我发送一些道具,与id相同,但没有与front_default属性,这是一个图像的网址。

javascript ajax reactjs api
4个回答
2
投票

由于ajax比反应渲染慢,因此您可以在获取数据之前使用加载组件。

const PokemonDetail = ({ pokemon }) => {
  if(pokemon.sprites == undefined){
      return(
        <div>
            Loading...
        </div>
      );
  }
  return (
    <div>
      <div className="text-center">{pokemon.name}</div>
      <img src={pokemon.sprites.front_default} alt={pokemon.name} />
      {pokemon.id}
    </div>
  );
};

1
投票

很可能只是一个AJAX问题,您的组件在有时间完成对API的请求之前呈现。尝试在渲染图像之前添加其他检查。

import React from "react";

const PokemonDetail = ({ pokemon }) => {
  return (
    <div>
      <div className="text-center">{pokemon.name}</div>
       {pokemon.sprites ? (
        <img src={pokemon.sprites.front_default} alt={pokemon.name} />
        ) : ( 
          null
        )
       }
      {pokemon.id}
    </div>
  );
};

export default PokemonDetail;

1
投票

@ZHAOXIANLONG为您提供了最佳解决方案(在接收数据之前使用加载组件),但是,如果您不使用加载组件,则可以使用lodash库[1]中的get方法以避免可能的错误。

import React from "react";
import _ from 'lodash';

const PokemonDetail = ({ pokemon }) => {
    const front_default = _.get(pokemon, 'sprites.front_default', 'DEFAULT_VALUE');
    const name = _.get(pokemon, 'name', 'DEFAULT_VALUE');

    return (
        <div>
            <div className="text-center">{pokemon.name}</div>
            <img src={pokemon.sprites.front_default} alt={pokemon.name} />
            {pokemon.id}
        </div>
    );
};

export default PokemonDetail;

其中第三个参数('DEFAULT_VALUE')是一个默认值,如果lodash无法为您的查询检索值,将使用该值。

PS:如果您知道可以更改API服务器,我建议您甚至在@ZHAOXIANLONG解决方案中使用lodash。

[1] https://lodash.com/docs/4.17.11#get


0
投票

最初的状态是{ pokemon: '' }; pokemon是一个空字符串。 PokemonDetail指的是pokemon.sprites.front_default,但pokemon最初是一个字符串,而一个字符串没有一个名为sprites的字段。

如果你期望pokemon最终成为一个对象,你可以将它初始化为看起来像一个对象的东西:

state = { pokemon: { sprites: {front_default: '' }}};
© www.soinside.com 2019 - 2024. All rights reserved.