简体   繁体   中英

ReactJS: how to access prop from child component

I'm learning React.js and I'm trying to make a website with the pokeAPI.

For one of my widget I want to display several pokemons with their statistics.

To do this, I have a main component that will call the API and populate my state array, then call a CardPokemon child component within a map to display each one of the pokemon.

Here is my problem, in my web console I can see that my different pokemons stats state array are filling up, but in the render of my main component the values of my array remain "undefined".

I tried to implement the first answer to this question: why react props are passed undefined to the child component? in my code, but I still have the same problem, the values of my array remain "undefined" in the render.

I put a part of my code here, any help would be greatly appreciated.

class CardPokemon extends Component {
  render() {
    return (
      <div className="Card">
        <div className="Card__img">
          <img src={this.props.pokemonImgProp[this.props.id]} alt="" />
        </div>
         ...
      </div>
    );
  }
}

class GenerationPokemonStat extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pokemonNameListAPI: [],
      pokemonImgAPI: []
      ...
    };
  }

  searchAllPokemon = () => {
    let number = 151; //for the 151 first pokemon
    Axios.get(`http://localhost:5000/getPokemonByGeneration/allPokemonGen/${number}`)
      .then(res => {
        var i;
        for (i = 0; i < number; i++) {
          let copyNameArray = this.state.pokemonNameListAPI.slice();
          copyNameArray[i] = res.data.results[i].name;
          this.setState({ pokemonNameListAPI: copyNameArray })
          
Axios.get(`http://localhost:5000/getPokemonByGeneration/one_pokemon_gen/${this.state.pokemonNameListAPI[i]}`)
            .then(response => {

              let copyImgArray = this.state.pokemonImgAPI.slice();
              copyImgArray[i] = response.data.sprites.front_default;
              this.setState({ pokemonImgAPI: copyImgArray });
      
              ...

              //everything display normally in web console here
              console.log(response);
              console.log(this.state.pokemonNameAPI[i]);
              console.log(this.state.pokemonImgAPI[i]);
            })
        }
      })
  }

  render() {
    let pokemonNameListAPI = this.state.pokemonNameListAPI;
    let pokemonImgAPI = this.state.pokemonImgAPI;

    //appears to be undefined in web console
    console.log(this.state.pokemonImgAPI[0]);

    if(!pokemonNameListAPI) {
        return null;
    }

    return (
      <>
        <div>
          <button onClick={this.searchAllPokemon}>Search Pokemon</button>
          {pokemonNameListAPI[151] === undefined ? <h1 style={{ textAlign: 'center' }}>Loading...</h1> : (
            <>
              <div className="grid-container">
                {pokemonNameListAPI.map((i) => {

                  //this console.log show me undefined for pokemonImgAPI[i]
                  console.log(pokemonImgAPI[i]);

                  return <CardPokemon
                    key={i}
                    id={i}
                    pokemonImgProp={pokemonImgAPI}
                  />
                })}
              </div>
            </>
          )}
        </div>
      </>
    );
  }
}

export default GenerationPokemonStat;

You should not try reading state immediately after setting it as state updates may be performed asynchronously (see State Updates May Be Asynchronous ). In your case this may mean the second axios call is not getting the parameter you expect and returning a null result.

In your searchAllPokemon method, when you perform the second axios call reference the copyNameArray variable instead of the pokemonNameListApi state variable.

Also, keep in mind that whenever you update state react will detect the state change and cause the component to refresh. You are currently performing two setState calls within a loop. Ideally you should construct your results into local variables and setState, once, outside the loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM