Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Getting wrong data stored in state variable when the correct data is being console logged

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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:

  1. You’re looping over the received resources, but reusing the same coinIds every time; that will lose previous updates and only keep the last one.

  2. You’re missing the [] in setCoinIds(...coinIds, res.id), so what you’re doing is spreading out the value of coinIds as discrete arguments to setCoinIds. But setCoinIds will ignore all but the first argument.

  3. 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 coinIds when setting the new value). You’re also doing asynchronous work, which means that coinIds may well be out of date by the time you do that. Instead, use the callback form of setCoinIds.

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.data getting an array of the id values 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 setCoinIds so that it’s using the most up-to-date state value.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading