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 ?
CodePudding user response:
you need to solve this problem like this:
setShowSpinner(true)
makeAPICall().then(res => {
setShowSpinner(false)
}).catch(err => {
console.log(err)
setShowSpinner(false)
})
CodePudding user response:
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
CodePudding user response:
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.
