簡體   English   中英

TypeError:無法使用React讀取undefined的屬性

[英]TypeError: Cannot read property of undefined using React

我是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;

PokemonDetail從中獲取Pokemon道具的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屬性(即圖像的網址)相同。

因為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> ); }; 

很可能只是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;

@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

初始狀態為{ pokemon: '' } pokemon是一個空字符串。 PokemonDetail引用的是pokemon.sprites.front_default ,但是pokemon最初是一個字符串,並且字符串沒有名為sprites的字段。

如果期望口袋妖怪最終成為對象,則可以將其初始化為看起來像對象的東西:

state = { pokemon: { sprites: {front_default: '' }}};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM