首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法访问map函数内部的数组以将属性返回到不同的组件

无法访问map函数内部的数组以将属性返回到不同的组件
EN

Stack Overflow用户
提问于 2019-07-31 08:53:10
回答 3查看 66关注 0票数 1

我正在从API中获取数据。我正在使用API调用构建一个由5个对象组成的数组。我试图做的是迭代数组,使用每个数组索引中的数据来构建一个组件,并将道具传递给另一个组件。

我尝试过像平常一样访问元素: img={pokemon.name},但它总是返回未定义的内容。当我输入console.log(精灵宝可梦)时,我得到存储在对象数组中的单个精灵精灵。

代码语言:javascript
复制
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

EN

回答 3

Stack Overflow用户

发布于 2019-07-31 09:15:09

componentDidMount在第一次渲染后执行,最初你的状态是pokemonArr: [] (其中为空),所以你会得到一个错误。你需要像这样有条件地渲染,

代码语言:javascript
复制
{this.state.pokemonArr.length > 0 && this.state.pokemonArr.map(pokemon => console.log(pokemon))}

旁注:

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

票数 0
EN

Stack Overflow用户

发布于 2019-07-31 09:19:05

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

buildPokemon()返回getPokemon() promise,并从它的then()返回对象

for()循环中,创建这些promises的数组,并在解析完所有这些promises之后使用Promise.all()设置状态

代码语言:javascript
复制
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 }));    
}
票数 0
EN

Stack Overflow用户

发布于 2019-07-31 09:32:14

问题主要是如何解决承诺。

数据不能立即可用,因此只有在数据可用时才应设置状态(pokemonArr)。

下面是重构后的组件:

代码语言:javascript
复制
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>
    );
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57281766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档