I’m doing an exercise to learn React in which I have set up a page with a list of clickable pokemon names which are linking to the pokemons specific detail page. Below is the code of the details page
import { useState, useEffect } from "react"; import axios from "axios"; import { useParams } from "react-router-dom"; export default function DetailsPage() { const pokeName = useParams(); console.log(pokeName); const [pokeList, setPokeList] = useState([]); useEffect(() => { const fetchData = async () => { const response = await axios.get( "https://pokeapi.co/api/v2/pokemon?limit=151" ); console.log(response.data); setPokeList(response.data.results); }; fetchData(); }, []); const specificPokemon = pokeList.find((pokemon) => { return pokemon.name === pokeName.pokemon_name; }); console.log(specificPokemon); console.log(specificPokemon.name); return <div><p>{specificPokemon.name}</p></div>; }
This code has an error I fail to understand
The console.log(specificPokemon)
works fine, but the console.log(specificPokemon.name)
gives me the following error
Uncaught TypeError: Cannot read properties of undefined (reading 'name')
The correct code is the following, but I wonder why my method doesn’t work
const [pokeList2, setPokeList2] = useState([]); useEffect(() => { const fetchData = async () => { const response = await axios.get( `https://pokeapi.co/api/v2/pokemon/${pokeName.pokemon_name}` ); console.log(response.data); setPokeList(response.data); }; fetchData(); }, []); console.log(pokeList);
Thank you
Advertisement
Answer
When your component is mounted, pokeList is an empty array.
React will run the following block before the useEffect hook has finished running:
const specificPokemon = pokeList.find((pokemon) => { return pokemon.name === pokeName.pokemon_name; }); console.log(specificPokemon); console.log(specificPokemon.name);
As long as your array is empty, specificPokemon
will be undefined
and calling specificPokemon.name
will trigger your error.
Beware with console.log
, its behavior is not always synchronous.
You might think specificPokemon
is properly defined because console.log
won’t necessarily show undefined
.
To verify this, use console.log(JSON.stringify(specificPokemon));
.