无法访问映射函数内部的数组以将道具返回给不同的组件



我正在从API获取数据。我正在使用 API 调用构建一个包含 5 个对象的数组。我正在尝试做的是遍历数组,使用每个数组索引中的数据来构建一个组件并将 props 传递给另一个组件。

我尝试以与通常相同的方式访问该元素: img={pokemon.name} 但它一直返回未定义。当我输入时 控制台.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;

应该发生的是,当我映射口袋妖怪Arr时,我想通过做创建5个单独的口袋妖怪this.state.pokemonArr.map(pokemon => <Pokecard name={pokemon.name}但是每当我在Pokecard组件中检查this.props时,我总是未定义。

我认为我的 buildPokemon() 函数是有效的,因为当我在组件 DidMount() 中调用它然后我在 render() 函数中控制台.logthis.state.pokemonArr我实际上得到了一个返回的数组,其中包含 5 个不同的口袋妖怪,并填写了正确的字段。

而且当我绘制出this.state.pokemonArr.map(pokemon => clg(pokemon))时,它实际上显示了每个单独的口袋妖怪。当我将口袋妖怪物品传递到这样的组件中时<Pokecard name={pokemon}/>,我看到了所有的口袋妖怪数据。 当我输入<Pokecard name={pokemon.name} I get undefined

你的方法有几个问题,但主要的问题是getPokemon()是异步的。

buildPokemon()返回getPokemon()承诺,并从其then()返回对象

for()循环中创建这些承诺的数组,并在它们全部解决后使用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 }));    
}
componentDidMount

在第一次渲染后执行,最初你的状态是pokemonArr: [](whch为空),所以你得到一个错误。你需要有条件地渲染,比如,

{this.state.pokemonArr.length > 0 && this.state.pokemonArr.map(pokemon => console.log(pokemon))}

旁注:

buildPokemon函数中,您返回一个array,再次在componentDidMount中将其存储在创建array of array'sarray中,您只需要从buildPokemon函数中返回object

问题主要在于应许应该如何解决。

数据不是马上可用的,所以状态(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>
);
}
}

最新更新