'calling setState multiple times not working properly

So I want to show spinner on my component every time it making API calls, what my function did is something like this:

setShowSpinner(true)
makeAPICall()
setShowSpinner(false)

It didnt work, only the last setShowSpinner was firing, and the spinner never showed up. I've heard that setState may be asynchronous, so I've tried something like:

setShowSpinner(true)
makeAPICall()
setShowSpinner(prevState => !prevState)

It didn't work either. Only when I wrap the second setShowSpinner inside setTimeout it works,

setShowSpinner(true)
makeAPICall()
setTimeout(() => setShowSpinner(false) ,someDelay)

but I think it is more of a hacky way instead of a good practice. Is there another way to improve it ?



Solution 1:[1]

you need to solve this problem like this:

setShowSpinner(true)
makeAPICall().then(res => {
   setShowSpinner(false)
}).catch(err => {
   console.log(err)
   setShowSpinner(false)
})

Solution 2:[2]

The best practice would to do something like this:

function fetchData() {
    setShowSpinner(true);
    makeAPICall()
     .then((result) => {
        // do what ever with the result
    })
     .catch((err) => {
        // do what ever with the result
    })
     .finally(() => {
        setShowSpinner(false))
    }
}

Finally makes sure that even though Promise was rejected, you won't enter infinite loading state. Read more in MDN documentation

Solution 3:[3]

You can use the Promise way like already mentioned in answers. I just wanted to give you another way of doing it. Probably you must be using a wrapper function for this loading spinner and API call. Let's check this way out.

const handleAPICall = async (args) => {
  setShowSpinner(true)
  // This will wait until your API call is pending or 
  // your Promise is resolved
  await makeAPICall()
  setShowSpinner(false)
}

You can still use .then() approach. It's upto you what you feel is good for you.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ttdat-thecodeguy
Solution 2 ldruskis
Solution 3 shivamragnar