I made a pokedex website, just to mess around and I try to render 12 pokemon to a page until the user click on the next page then it will render the next 12 base on the pokeapi: "https://pokeapi.co/api/v2/pokemon?offset=0&limit=12"
function getAllPokemon(url) {
fetch(url)
.then((res) => res.json())
.then((data) => {
let allPromise = Promise.all(
data.results.map((e) => {
return new Promise((resolve, reject) => {
resolve(e);
});
})
);
allPromise.then((e) => {
e.map((res) => {
fetch(res.url)
.then((e) => e.json())
.then((e) => {
setListPokemon((listPokemon) => [
...listPokemon,
{
id: e.id,
name: res.name,
url: res.url,
image_url:
e.sprites.other["official-artwork"].front_default,
},
]);
});
});
});
});
setLoading(false);
}
Then I would use map to render all the data to screen.
{listPokemon.map((p) => (
<Grid>
<Card>
<CardMedia
component="img"
image={p.image_url}
alt={p.name}
/>
<CardContent>
{p.id}.{setCap(p.name)}
</CardContent>
</Card>
</Grid>
))}
The problem I have is sometimes map would render the element in random order, most of the time it would still be in ascending order.
From what I notice is that when I try running the app on my phone (which is slower than my PC) this happens more often.
Is this happen because of lag?
Is there a way to make sure that I render the element in the order of which is added?
CodePudding user response:
Notice that you are making asynchronous requests inside a for
loop. You should make an array of promises and use Promise.all() in such a case. The result will be in a specific order, as explained here, so you will be able to update your state only once with sorted collection of data and then render your list.