Как выполнить цикл for с помощью React и почему мой компонент не отображается

#javascript #reactjs #create-react-app

#javascript #reactjs #create-react-app

Вопрос:

 import React, { Component } from "react";
import Pokecard from "./Pokecard";
import "./Pokedex.css";

class Pokedex extends Component {
  static defaultProps = {
    pokemon: [],
    getData() {
      for (let i = 1; i <= 40; i  ) {
        fetch(`https://pokeapi.co/api/v2/pokemon/${i}`)
          .then((response) => response.json())
          .then((data) => {
            this.pokemon.push({
              id: data.id,
              namePoke: data.name,
              type: data.types[0].type.name,
              base_experience: data.base_experience,
            });
          });
      }
    },
  };
  render() {
    this.props.getData();
    return (
      <div className="Pokedex">
        <div className="Pokedex-grid">
          {this.props.pokemon.map((p) => (
            <Pokecard
              id={p.id}
              name={p.namePoke}
              type={p.type}
              exp={p.base_experience}
              key={p.id}
            />
          ))}
        </div>
      </div>
    );
  }
}

export default Pokedex;
 

Я новичок в React, и я не понимаю, почему мой цикл for выполняется несколько раз, поэтому я получаю Pokecards дважды или более.
Кроме того, весь компонент Pokedex не отображается при перезагрузке страницы. Что я делаю не так?

Комментарии:

1. render вызывается всякий setState раз, когда вызывается get, что означает, что у вас бесконечный цикл. изучите использование методов жизненного цикла, таких как componentDidMount reactjs.org/docs/react-component.html

Ответ №1:

@azium сделал отличный комментарий. Вы вызываете, чтобы получить данные в вашем рендеринге, который устанавливает состояние, и вызываете повторный рендеринг, который снова вызывает getData, который снова извлекает данные, а затем снова устанавливает состояние, и цикл продолжается бесконечно. Кроме того, реквизиты по умолчанию должны определять только значения свойств по умолчанию, но в этом случае вам не нужен реквизит getData по умолчанию. Все, что вам нужно сделать, это вызвать метод getData в вашем componentDidMount. И ваш метод должен сохранять данные в состоянии, а не выполнять прямое изменение свойств (как вы делаете). Вот один из примеров:

 import React, { Component } from "react";
import Pokecard from "./Pokecard";
import "./Pokedex.css";

class Pokedex extends Component {
  static state = {
    pokemon: []
  };
  componentDidMount() {
    this.getData();
  }
  getData() {
      for (let i = 1; i <= 40; i  ) {
        const pokemon = [...this.state.pokemon];
        fetch(`https://pokeapi.co/api/v2/pokemon/${i}`)
          .then((response) => response.json())
          .then((data) => {
            pokemon.push({
              id: data.id,
              namePoke: data.name,
              type: data.types[0].type.name,
              base_experience: data.base_experience,
            });
        });
        this.setState({pokemon});
      }
  }
  render() {
    return (
      <div className="Pokedex">
        <div className="Pokedex-grid">
          {this.state.pokemon.map((p) => (
            <Pokecard
              id={p.id}
              name={p.namePoke}
              type={p.type}
              exp={p.base_experience}
              key={p.id}
            />
          ))}
        </div>
      </div>
    );
  }
}

export default Pokedex;