I want to be sure that when
showComponentPropis updated, that the firstuseEffectupdates the state before the second useEffect is run.
The first useEffect hook's callback will certainly enqueue the isVisible state update before the second useEffect hook is called.
I understand that
useEffecthooks are run in the order they appear in the component body, however, as these contain setState functions, I'm not 100% sure of the behaviour. I don't want there to be a race condition between the two setState functions in theuseEffecthooks.
All React hooks are called each render cycle, in the order they are defined. If showComponentProp changes, then because it is included in the dependency array of both useEffect hooks it will trigger the both useEffect hooks' callbacks, in the order they are defined.
Could someone please clarify the exact order of the useEffects being called and when the component is rerendered in this case. For instance, is the first effect called, and when the
isVisiblestate is updated, does the component rerender before the second effect is called? In that case will both effects be run again after the rerender, or just the second effect as the first effect was called previously.
useEffect hook callbacks will be called, in order.
isVisible state update to update to the current showComponentProp value.showComponentProp and timerProp values, and if both are truthy enter the if-block and instantiate the timeout to enqueue another isVisible state update to false, and return a useEffect hook cleanup function.timerProp ms and calls the callback to enqueue another isVisible state update to false, and trigger another component rerender, e.g. back to step 1 above.In any case, both useEffect hooks will be called each and every render cycle, and the callbacks called only when the dependencies change.
However, I suspect you could accomplish this all in a single useEffect hook, which may make understanding the logic and flow a bit easier.
const [isVisible, setIsVisible] = useState(showComponentProp);
// Run effect when either showComponentProp or timerProp update
useEffect(() => {
// Only instantiate timeout when we've both truthy
// showComponentProp and timerProp values
if (showComponentProp && timerProp) {
// Enqueue isVisible state update "now"
setIsVisible(true);
// Enqueue timeout to enqueue isVisible state update "later"
const timeout = setTimeout(() => setIsVisible(false), timerProp);
return () => clearTimeout(timeout);
}
}, [showComponentProp, timerProp]);