I am trying to store data in my state. When I console log the data I get the correct data. When I store it in my state and console log it, I keep getting "c" in my console. Why is C being stored in my state when there is no sign of "c" in my entire code
This keeps giving me C in my console.
const getIds = async () => {
Axios.get(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false"
).then((response) =>
response.data.map((res) => setCoinIds(...coinIds, res.id))
);
console.log(coinIds);
};
This logs the correct data:
const getIds = async () => {
Axios.get(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false"
).then((response) => response.data.map((res) => console.log(res.id)));
};
Why is the data not stored in my state?
>Solution :
There are a few things going on:
-
You’re looping over the received resources, but reusing the same
coinIdsevery time; that will lose previous updates and only keep the last one. -
You’re missing the
[]insetCoinIds(...coinIds, res.id), so what you’re doing is spreading out the value ofcoinIdsas discrete arguments tosetCoinIds. ButsetCoinIdswill ignore all but the first argument. -
Separately from #1, you could well also be running into the "stale closure" problem. Your code is setting state based on existing state (by using
coinIdswhen setting the new value). You’re also doing asynchronous work, which means thatcoinIdsmay well be out of date by the time you do that. Instead, use the callback form ofsetCoinIds.
Separately, the console.log at the end fo getId will show you the value prior to the Axios callback, so it’s not giving you any useful information and could be confusing.
Fixing all three issues:
const getIds = async () => {
Axios.get(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false"
).then((response) =>
setCoinIds(coinIds => [...coinIds, ...response.data.map(res => res.id)]);
);
};
That does this:
- Loops through
response.datagetting an array of theidvalues of each of the data objects. - Makes only a single call to
setCoinIds, filling in all the new values at once. - Uses
[]so we’re passing a single array. - Uses the callback form of
setCoinIdsso that it’s using the most up-to-date state value.