我是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从中获取神奇宝贝道具的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
属性(图像的网址)上则无效。
答案 0 :(得分: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 :(得分: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;
答案 2 :(得分:1)
@ZHAOXIANLONG为您提供了最佳解决方案(在您接收数据之前使用加载组件),但是,如果不使用加载组件,则可以使用 lodash中的 get 方法库[1],以避免可能的错误。
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。
答案 3 :(得分:0)
初始状态为{ pokemon: '' }
; pokemon
是一个空字符串。 PokemonDetail
指的是pokemon.sprites.front_default
,但是pokemon
最初是一个字符串,并且字符串没有名为sprites
的字段。
如果希望口袋妖怪最终成为对象,则可以将其初始化为看起来像对象的东西:
state = { pokemon: { sprites: {front_default: '' }}};