反应-无法呈现元素数组

时间:2019-08-08 16:48:49

标签: javascript reactjs

我无法使用JSX将对象数组呈现到视图中。它不会在屏幕上加载。

我一直在学习React,可以渲染字符串数组,但是不能渲染对象数组。

这是我的组成部分:

import React, { Component } from "react";

export default class PokedexGridComponent extends Component {
  constructor(props) {
    super(props);
    console.log(props);

    this.state = {
      pokemons: [],
      all: []
    };
  }

  componentDidMount() {
    this.getPokemons();
  }

  render() {
    return (
      <div>
        <input
          className="btn btn-success btn-sm mb-5"
          type="button"
          onClick={this.getPokemons}
          value="Buscar Pokemons"
        />
        <div>
          {this.state.all.map(data => {
            return <li key={data.key}>{data.name}</li>;
          })}
        </div>
      </div>
    );
  }

  getPokemons = () => {
    var pokemon = [];
    fetch("https://pokeapi.co/api/v2/pokemon?offset=20&limit=964")
      .then(data => {
        return data.json();
      })
      .then(data => {
        data["results"].forEach(data => {
          pokemon.push(data.name.charAt(0).toUpperCase() + data.name.slice(1));
        });

        this.setState({ pokemons: pokemon });
        return this.state.pokemons;
      })
      .then(data => {
        var tmp = [];
        this.state.pokemons.forEach((data, idx) => {
          fetch(`https://pokeapi.co/api/v2/pokemon/${data.toLowerCase()}`)
            .then(data => {
              return data.json();
            })
            .then(data => {
              tmp.push({
                name: data.name,
                image: data.sprites.front_default,
                key: idx
              });
            });
        });

        this.setState({ all: tmp });
        console.log(this.state.all);
      });
  };
}

控制台返回对象数组,但无法将其映射到render方法上。

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:0)

setState方法是异步的,因此,如果在更新状态后需要执行某些操作,则需要使用第二个参数,该参数是在更新状态后将执行的功能。

this.setState({ pokemons: pokemon }, function(){
   //perform what you need with the updated
})

您遇到的另一个问题是,您要在请求到达之前进行更新。您可以收集所有承诺并将其应用于Promise.all

const requests = []
pokemons.forEach((data, idx) => {
  const request = fetch(`https://pokeapi.co/api/v2/pokemon/${data.toLowerCase()}`)
    .then((data) => {
      return data.json();
    })
  requests.push(request)
})

const tmp = [];
Promise.all(request).then((arrayOfResults) => {
  //Here you have the responses to iterate
  arrayOfResults.forEach((data) => {
    tmp.push({
      name: data.name,
      image: data.sprites.front_default,
      key: idx
    })
  })
  this.setState({all: tmp}, function(){
    //here you can see the state after update
  })
})

答案 1 :(得分:0)

Promise.all一起工作,谢谢 @SergioEscudero @Vencovsky

这是修改后的代码:

import React, { Component } from 'react'

export default class PokedexGridComponent extends Component {

constructor(props) {
    super(props);
    this.state = {
        pokemons: [],
        pokeComplete: []
    }
}

componentDidMount() {
    this.getPokemons();
}

render() {
    return (
        <div>
            <input className="btn btn-success btn-sm mb-5" type="button" onClick={this.getPokemons} value="Buscar Pokemons" />
            <div>
               {
                   (this.state.pokeComplete.map((data) => {
                       return (<li>{data.name} | {data.img}</li>)
                   }))
               }
            </div>
        </div>
    )
}

getPokemons = () => {
    var pokemons = [];
    fetch("https://pokeapi.co/api/v2/pokemon?offset=20&limit=964")
        .then((data) => {
            return data.json();
        })
        .then((data) => {
            data["results"].forEach((data) => {
                pokemons.push(data.name)
            })

            return pokemons;
        }).then((data) => {
            var arrayReq = [];
            data.forEach((x) => {
                var req = fetch(`https://pokeapi.co/api/v2/pokemon/${x.toLowerCase()}`)
                    .then((data) => {
                        return data.json();
                    })
                arrayReq.push(req);
            })

            var tmp = [];
            Promise.all(arrayReq)
                .then((e) => {
                    e.forEach((x) => {
                        tmp.push({
                            name: x.name,
                            img: x.sprites.front_default
                        })
                    })
                })
                .then(() => {
                    this.setState({ pokeComplete: tmp });
                })
        })
    }
}