Home > Net >  Is there a better way to store data from an API in state?
Is there a better way to store data from an API in state?

Time:11-07

I'm developing the interface of a music web app , so i fetched data from an API and stored in state, all executed by one function , to be displayed on the interphase .The code is below :

/* function fetching the data*/
  function getUsChart() {
    const options = {
      method: 'GET',
      headers: {
        'X-RapidAPI-Key': '036795ec2amsh8c2b98ef8a502acp146724jsn6f3538b26522',
        'X-RapidAPI-Host': 'shazam-core.p.rapidapi.com'
      }
    };
    
    fetch('https://shazam-core.p.rapidapi.com/v1/charts/genre-country?country_code=US&genre_code=HIP_HOP_RAP', options)
      .then(response => response.json())
      .then(response => setUsHopChart(response))
      .catch(err => console.error(err));
/*I stored it in state here*/
      setChartImg(usHopChart[1]?.images?.coverart)
  }
/*I displayed it here*/
             <img src={chartImg} className='chart-img rounded-3xl' alt='chart-image'/>

The issue: After the function is executed , the data is fetched but not stored it in the state immediately until it's executed the second time. Hence causing this : enter image description here

What can i do about this please?

CodePudding user response:

i think you need to move the setChartImg inside

  fetch('https://shazam-core.p.rapidapi.com/v1/charts/genre-country?country_code=US&genre_code=HIP_HOP_RAP', options)
      .then(response => response.json())
      .then(response => {
        setUsHopChart(response)
        setChartImg(response[1]?.images?.coverart)
    })
      .catch(err => console.error(err));
/*I stored it in state here*/
      

CodePudding user response:

I think the problem is jsx is rendered before the fetch process is done. So, it is the best approach to create a boolean loading state and initialize it with true, when it's value is true create a spinner or smth and make it false when promise returns the value.

For quick solution maybe you can do something like that:

{chartImg && <img src={chartImg} className='chart-img rounded-3xl' alt='chart-image'/>}

So what it does is when chartImg is defined (when you give it a value after promise resolves) it will render the jsx element, which was your problem.

  • Related