我正在从API中获取数据。我正在使用API调用构建一个由5个对象组成的数组。我试图做的是迭代数组,使用每个数组索引中的数据来构建一个组件,并将道具传递给另一个组件。
我尝试过像平常一样访问元素: img={pokemon.name},但它总是返回未定义的内容。当我输入console.log(精灵宝可梦)时,我得到存储在对象数组中的单个精灵精灵。
import React, { Component } from "react";
import Pokecard from "./Pokecard";
async function getPokemon() {
const randomID = Math.floor(Math.random() * 151) + 1;
const pokeRes = await fetch(`https://pokeapi.co/api/v2/pokemon/${randomID}/`);
const pokemonJSON = await pokeRes.json();
return pokemonJSON;
}
function buildPokemon() {
let pokemonArr = [];
let builtPokemon = {};
getPokemon()
.then(data => {
builtPokemon.name = data.forms[0].name;
builtPokemon.exp = data.base_experience;
builtPokemon.img = data.sprites.front_default;
builtPokemon.type = data.types[0].type.name;
pokemonArr.push(builtPokemon);
})
.catch(err => console.log(err));
return pokemonArr;
}
class Pokedex extends Component {
constructor(props) {
super(props);
this.state = { pokemonArr: [] };
}
componentDidMount() {
const pokemonArr = [];
for (let i = 0; i < 5; i++) {
pokemonArr.push(buildPokemon());
}
this.setState({ pokemonArr });
}
render() {
console.log(this.state.pokemonArr);
return (
<div className="Pokedex">
{this.state.pokemonArr.map(pokemon => console.log(pokemon))}
</div>
);
}
}
export default Pokedex;应该发生的是,当我映射pokemonArr时,我想通过执行this.state.pokemonArr.map(pokemon => <Pokecard name={pokemon.name}来创建5个单独的口袋妖怪,但每当我在Pokecard组件中检查this.props时,我都会得到未定义。
我认为我的buildPokemon()函数是有效的,因为当我在componentDidMount()中调用它,然后在console.log ()函数中呈现this.state.pokemonArr时,我实际上得到了一个数组,其中包含5个不同的pokemon,并填充了适当的字段。
而且当我绘制this.state.pokemonArr.map(精灵宝可梦=> clg(精灵宝可梦))时,它实际上会显示每个精灵。当我将“精灵宝可梦”项目传递给一个像这样的<Pokecard name={pokemon}/>组件时,我会看到所有的精灵宝可梦数据。当我键入<Pokecard name={pokemon.name} I get undefined时
发布于 2019-07-31 09:15:09
componentDidMount在第一次渲染后执行,最初你的状态是pokemonArr: [] (其中为空),所以你会得到一个错误。你需要像这样有条件地渲染,
{this.state.pokemonArr.length > 0 && this.state.pokemonArr.map(pokemon => console.log(pokemon))}旁注:
在buildPokemon函数中,您将返回一个array,在componentDidMount中,您将其存储在创建array of array's的array中,您只需从buildPokemon函数返回object。
发布于 2019-07-31 09:19:05
您的方法有几个问题,但最主要的问题是getPokemon()是异步的。
从buildPokemon()返回getPokemon() promise,并从它的then()返回对象
在for()循环中,创建这些promises的数组,并在解析完所有这些promises之后使用Promise.all()设置状态
function buildPokemon() {
let builtPokemon = {};
// return the promise
return getPokemon()
.then(data => {
builtPokemon.name = data.forms[0].name;
builtPokemon.exp = data.base_experience;
builtPokemon.img = data.sprites.front_default;
builtPokemon.type = data.types[0].type.name;
// return the object
return builtPokemon
});
}
componentDidMount() {
const pokemonPromises = [];
for (let i = 0; i < 5; i++) {
pokemonPromises.push(buildPokemon());
}
Promise.all(pokemonPromises).then(pokemonArr => this.setState({ pokemonArr }));
}发布于 2019-07-31 09:32:14
问题主要是如何解决承诺。
数据不能立即可用,因此只有在数据可用时才应设置状态(pokemonArr)。
下面是重构后的组件:
class Pokedex extends Component {
constructor(props) {
super(props);
this.state = { pokemonArr: [] };
}
componentDidMount() {
for (let i = 0; i < 5; i++) {
this.getPokemon()
.then((pokemon) => this.buildPokemon(pokemon));
}
}
async getPokemon() {
const randomID = Math.floor(Math.random() * 151) + 1;
const pokeRes = await fetch(`https://pokeapi.co/api/v2/pokemon/${randomID}/`);
return pokeRes.json();
}
setPokemon(pokemon) {
this.setState({
pokemonArr: [
...this.state.pokemonArr, pokemon
],
});
}
buildPokemon(data) {
let builtPokemon = {};
builtPokemon.name = data.forms[0].name;
builtPokemon.exp = data.base_experience;
builtPokemon.img = data.sprites.front_default;
builtPokemon.type = data.types[0].type.name;
this.setPokemon(builtPokemon);
}
render() {
return (
<div className="Pokedex">
{this.state.pokemonArr.map(pokemon => console.log(pokemon))}
</div>
);
}
}https://stackoverflow.com/questions/57281766
复制相似问题