Step 1 of 5 · Reading · ~2 min
Read
Hooks & State
The useState Hook
A hook gives a plain function component something that survives between renders.
The component function runs again from the top on every render, so count
cannot be a local variable. It lives outside, in a slot list owned by the
component instance.
Why the rule of hooks exists
Read that code again: a hook has no name and no identity. The first
useState call of a render gets slot 0, the second gets slot 1, and so on.
Put one behind an if and skip it on the next render, and every hook after
it shifts down a slot - your age now reads the value stored for name,
silently. That is the whole reason hooks may not go inside conditionals or
loops.
The functional setter
count is a value captured when that render ran. The functional form asks
the slot for what it holds right now, which is the only form that composes
under batching or inside an async callback.
Passing a function to useState itself means something different - it is a
lazy initialiser, run once on mount: useState(() => parse(bigBlob)).
Two things built on the same slots
useReducer stores a state object and a reducer, and dispatch(action)
runs it - the same slot machinery, a better fit once the transitions get
interesting. useContext reads a value from the nearest provider above,
which is how you skip threading a prop through six layers that do not care
about it. Context delivers a value; it does not store one.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…