I’m trying to wrap my mind around the semantics of discarded renders which I understand can happen in concurrent mode.
I would expect that if a render is discarded then none of the useEffect()s are called. Firstly, because useEffects() should run after the commit and well at commit the render is not being discarded by definition.
Is this correct, or do useEffect()s run on discarded renders as well?
2
Answers
It may or may not be the case, but you shouldn’t rely on this behaviour as whatever it does now might change in future versions of React.
The docs are vague on purpose (https://react.dev/reference/react/useEffect#useeffect, note the "generally" and "may"):
But generally speaking, it should not matter, because you should design your effects with a cleanup function, in a way that it doesn’t make a difference whether it runs or not (as long as it gets cleaned up). Effects are used for synchronizing with external systems, not for irreversible side effects.
You are almost correct buddy but I will tell you how it works.
While in concurrent mode a render can be discarded if the component state changes before the render is committed to the DOM. The main purpose is optimization (makes sense right, why have unnecessary updates).
Now the use useEffect hook runs only after the component is committed to the DOM. It runs after the render cycle is completed, which means all updates to the DOM are finalized.
Since this is the case useEffect will not run for discarded renders. if a render is discarded, any effects associated with that render will not execute too.
Hope this answer helps you