I'm using a useEffect to show a UI Loading... but only after 250ms. It works ... but I really don't understand why and specially how and when useEffect invokes the returned function (that clears the timeout).
Well ... I'm not sure that's work perfectly. Sometimes the "Loading ..." message should appear but it's not.
const [loadingAfterShortTime, setLoadingAfterShortTime] = useState(false);
useEffect(() => {
setLoadingAfterShortTime(bool => false);
if (myDepandanceToTrigTheLoadingWord === true) {
const id = setTimeout(() => {
setLoadingAfterShortTime(bool => true);
}, 250);
return () => {
clearTimeout(id);
};
}
}, [myDepandanceToTrigTheLoadingWord]);
The explanation provided by @Powell Ye is good however there a bit of erroneous information specifically when speaking about re-renders (e.g. when props change)
consider some simple component with the following
useEffect( () => {
console.log('Effect is applied')
//some logic
return () => {
console.log('cleaning up')
//cleanup logic
}
})
return (<>
{console.log('rendering...')}
</>)
say the props passed in changes you might think it goes as such
However, the following actually occurs
That is, the clean up function runs AFTER the new render/painting but BEFORE the 'new' effects are applied, the docs can be a bit ambigious about this
the previous effect is cleaned up before executing the next effect
This is done for performance reasons => so that rendering is not delayed ( it can be frustrating at times for me too )
Here's an outline of the timings involved:
useEffect
is called on the initial render and whenever any of the values it depends on change. In general, it fires after the rendering is completed. If you think of it in terms of a class-based component, equivalent would be componentDidMount
method.useEffect
is invoked before the component is removed from the UI or is about to re-render (to avoid memory leaks). Previous effect is always cleaned up before performing the next effect. It's guaranteed to run before any new renders. Equivalent would be componentWillUnmount
.Let's assume that there is a useEffect
with few dependencies made of props (which are passed to our component) + a cleanup function. On the first render, the following would happen:
Now let's imagine something triggers a re-render. Since it's listed as something useEffect
depends on, the effect will be re-executed as following:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With