How React hooks associate functions with state
A question I had for a long time was: how do React hooks work?
Specifically, how do they associate a functional component with state, without requiring a stable identifier?
There are many high quality answers online. For me, they either focus to deeply on React internals (Fibers, render cycle, ReactFiberHooks), or they are too high level (“it’s just arrays”, closures, call order).
Here is an answer for me1:
- A JSX tag is transformed into a function call, passing in the tag name as a string, properties as an object, and its children as expressions (recursively transformed as well).
- The children of a JSX element are transformed into positional function arguments2 that have a stable order. This is stable even if they are conditionally rendered, since the conditional expression occupies the argument slot. List expressions need keys because JSX transforms them into a single argument.
- Hooks use order within the JSX tree to index into which component state to load.
- Hooks within the same component are distinguished by call order in that component. This is possible because of the Rules of Hooks.
References
- Build your own React (Rodrigo Pombo): this was helpful in understanding how JSX transforms into Javascript, which is the key that a lot of other resources missed or assumed. Very detailed!
- Getting Closure on React Hooks (swyx): this explains closure for hooks and derives the rules of hooks.
- Making Sense of React Hooks (Dan Abramov): introduces some benefits of hooks and talks about the implementation at a high level
- Also, the linked pseudocode from @jamiebuilds
- Introducing JSX (legacy React docs): outdated (
_jsxis now called instead ofReact.createElement) but useful context - StackOverflow answer from Knight Industries: provided some intuition, not as useful on its own
- Asking questions to Claude was helpful in honing my understanding, especially for the conditional rendering question with JSX, which I verified with Babel.
- Hooks FAQ: How does React associate hook calls with components (legacy React docs): the is the former “official” answer, but it’s very high level.
-
I like lists and bullets and I am not AI. Tautology.town is written by hand! I like em-dashes too, but that battle has been lost. ↩
-
“Parameter” and “argument” can be conflated, but strictly speaking a parameter is the name in the function definition and argument is the actual value supplied. That distinction is important here. ↩