Hey, I am React with hooks. There's something apparently not many people tell you about how I work.
A nuance on top of how React's hooks flow is usually taught

Down the rabbit hole
Give me a component A and I'll:
On first render
- Run
A'sstate lazy initializers. - Render
A. - Update the
DOM. - Run
A'slayout effects. - Paint the
DOMupdates from3. - Run
A'seffects.
On subsequent renders (props changed or state changed)
- Render
A. - Update the
DOM. - If any of
A'slayout effects don't have a dependency array or any of its dependencies has changed, run their clean-up functions. - If any of
A's layout effect's don't have a dependency array or any of its dependencies has changed, run them. - Paint the
DOMupdates from2. - If any of
A'seffects don't have a dependency array or any of its dependencies has changed, run their clean-up functions. - If any of
A'seffects don't have a dependency array or any of its dependencies has changed, run them.
When rendering your app doesn't render A anymore
- Run
A'slayout effects' clean-up functions. - Run
A'seffects' clean-up functions.
The nuance
You have probably seen (if not, you should take a deep look!) this before:
It does an awesome job at explaining the order and the phases on which stuff happens, but even though most React devs understand when their effects run, I've seen them having a hard time understanding not every rerender trigger clean-ups.
When a new rerender happens, dependencies are checked. If any of the dependencies changed (or there's no dependencies array), it cleans up the previous
effectbefore rerunning theeffect.
What's a clean-up function?
The clean-up function run on the Nth render is the function returned by an effect on render Nth - 1.
Beware! This means clean-up functions on render Nth will likely be closed over (hold a closure of) Nth - 1's state!
When does a dependency change?
React uses Object.is to compare dependencies. Object.is is an strict equality check (===) on esteroids: while the strict equality comparison algorithm is meant to lie about 0 === -0 and NaN === NaN to comply with IEEE 754, Object.is doesn't.
Try it yourself
Sandbox here.
Glossary
Render(andrerender): run a functional component's body or run a class component'srendermethod. Obtaining theJSXreturned from it and handing it to React so it knows how to update theDOM.Update the DOM: performDOMmutations through actual JS'sDOMAPI. Updating theDOMsynchronously schedules tasks to repaint the screen that will happen asynchronously.- Paint the
DOMupdates: giving the browser a break so it can paint any scheduledDOMupdate.


