It works when I stay on this page. However, when I switch to another tab and come back while the api is processing, setLoading(false) is never triggered.
How can I fix this?
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(!!window.sessionStorage.getItem("isButtonDisabled");
}, []);
useEffect(() => {
console.log(loading);
}, [loading]);
const showReport = () => {
setLoading(true);
window.sessionStorage.setItem("isButtonDisabled", true);
return axios({
url: 'api/report/getdata',
method: 'GET',
responseType: 'blob'
}).then(() => {
window.sessionStorage.setItem("isButtonDisabled", false);
setLoading(false);
});
};
2
Answers
You might want to use
.finally()
because.then()
is triggered only if the promise finishes successfully. More details about finally in Mozilla Docs.To resolve the issue, you might also want to use
useEffect()
cleanup to call a callback to stop the loading whenever the component gets unmounted.ReportLoadingPanel
is showing forever because:window.sessionStorage.getItem("isButtonDisabled")
always returns a string, so, conversions toboolean
:!!'true'
is equals totrue
and!!'false'
is equals totrue
also. The correct check would look like this:window.sessionStorage.getItem("isButtonDisabled") === 'true'
.then()
, to solve this, add a call of.catch()
after.then()
and callsetLoading(false)
andwindow.sessionStorage.setItem("isButtonDisabled", false)
there too, or, as mentioned above, you can use.finally()
, as it is being fired regardlessPromise
is resolved or rejected.useEffect
hook and move logic from there touseState
hook: