-
Notifications
You must be signed in to change notification settings - Fork 49.2k
Description
To my understanding, useEffect
should always run after the browser acutally did paint any updates. This way, I tried to ensure that a loading indicator is rendered after a user submits data but before a blocking function execution (e.g. a fetch operation where the data is waited on) is executed. The code looks somewhat like the following:
Wrapper component to which a loading indicator can be passed:
export const LoadingWrapper = ({ callback, children}) => {
useEffect(() => {
if (typeof callback === "function") callback();
}, [])
return <React.Fragment> {children} </React.Fragment>
}
Usage:
const [loading, setLoading] = useState(false);
const blockingFunction = () => {
// some functionaliy which blocks painting updates
}
return (
// some kind of input elements which change the `loading` state on submit
{ loading &&
<LoadingWrapper callback={blockingFunction}>
<div> Loading! </div>
</LoadingWrapper>
)
I would expect from the documentation that the callback
function is executed after the "Loading" div is rendered on the screen, but that is actually not the case. The new div appears after the blocking call is completely resolved.
To get it working, I acutally have to use a local state variable in addition to trigger the effect:
export const LoadingWrapper = ({ callback, children}) => {
const [isMounted, setIsMounted] = useState(false)
useEffect(() => {
setIsMounted(true);
}
useEffect(() => {
if (isMounted && typeof callback === "function") callback();
}, [isMounted]
return <React.Fragment> {children} </React.Fragment>
}
Using this, I also observed some strange browser dependent behaviour. If input changes (which lead loading
being set to true
) are submitted onBlur
of the input, it works fine in Chrome as well as in Firefox. Submitting these changes onKeyPress
(while checking if the pressed key was the Enter
key), it works in Firefox, but not in Chrome.
Does anyone have an idea what exactly is going on here or do I miss something important?
UPDATE:
I added a code sandbox: https://codesandbox.io/s/effectrendering-umtwo
The behaviour is quite strange:
In Chrome, triggering onBlur
works (almost) always, sometimes it seems to bug out. Triggering onKeyPress
will never trigger the spinner, except when onBlur
was triggered before with the exact same input string (even though this string should have no influence at all here).
In Firefox, neither onBlur
nor onKeyPress
will trigger the spinner for me.
Tested versions:
Chrome 88.0.4324.150 (64-Bit)
Firefox 85.0.2 (64-Bit)