I am trying to display data fetched from API with React.
I am fetching the data from https://pokeapi.co/docs/v2, and I intend to display the names and urls retuned and also manipulate them to practice conditional rendering, etc
But it seems that I have run into an infinite loop.
I have googled and it suggests me to use React.useEffect()
But even if I did this, I still get the errors:
Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
My code are as below:
App.js
import React from 'react'
import PokemonList from "./PokemonList";
function App() {
const [pokemons, setPokemons] = React.useState([]);
React.useEffect(() => {
console.log('fetch ran')
fetch('https://pokeapi.co/api/v2/pokemon').then(res => res.json())
.then(data => {
setPokemons(() => data);
})
}, [])
return (
<div>
<PokemonList pokemons={pokemons} />
</div>
)
}
export default App;
PokemonList.js:
import React from 'react'
export default function PokemonList({ pokemons }) {
const [pokemonsArray, setPokemonsArray] = React.useState([]);
setPokemonsArray(()=>pokemons.results)
const pokemonsElements = pokemonsArray.map((pokemon) => {
return (
<div key={pokemon.name}>
<h3>{pokemon.name}</h3>
<p>{pokemon.url}</p>
<hr />
</div>
)
})
return (
<div>
{pokemonsElements}
</div>
)
}
Sometimes I would also get the error:
Consider adding an error boundary to your tree to customize error handling behavior.
react-refresh-runtime.development.js:315 Uncaught TypeError: Cannot read properties of undefined (reading 'map')
I assume this is bc I try to run .map() when the data has not been returned yet….
Can anyone help me? Sorry if it is a stupid question but I have been stuck for so long and could not find answers. What is the correct way to do this?
2
Answers
You’re trying to set the state directly inside the component which means that every time the component renders, and its state is updated which causes a re-render and then you set the state again, causing another re-render.
It is exactly as you stated. The reason
map
inpokemonsArray.map
is being undefined is because it is immediately being accessed before the component is mounted and is ready.Here is how you would do it by fixing in
App
andPokemonList
In
App
, you do not need to make a callback onsetPokemons
as you can directly pass the value.App:
Check if
pokemons
is unavailable in which case return null or call a spinner component or similar which shows that the list is empty or being loaded.PokemonList
The error is in this line:
Btw, I recommend the use of react-query.
With RQ: