Hacker News new | ask | show | jobs
by joelg236 2794 days ago
In the keynote, Dan talked about how this works. It depends on the order that useState is called, which makes conditional branches a no-no (there's a linter for it).
3 comments

Since JS is single threaded, they are basically keeping track of which component was last called for render - that way they know useState() calls attached to which components. If the order changes, then they can't keep track of the different objects tracked by useState. So treat it like you would class state - all fields are always there, no matter which functions or conditional branches you take - hence - do your initialization above all your conditionals and loops.

Edit: And yes, slight concern of course, it's the got some rough semantic equivalents to a thread-local in Java, albeit in Java the danger exists downstream, this danger is only exhibited during initialization it seems.

IIUC, the order isn't used to figure out which React component is being rendered, but which of potentially several hook invocations within that single component is currently being invoked. If every unique hook could only be (directly or indirectly) called a single time per component, then there wouldn't need to be this ordering restriction. (Or more realistically, if each hook call also took an ID that is unique per-component.)
Just looking at the code I came to the conclusion it had to work that way, I don't like it, way too easy to break and some people are going to be very confused when things goes wrong. It's a uncommon/unfamiliar coding constraint. If you have to declare them all in the same order every time, you might as well force a single state (like the setState API) and/or keyed state values and have a safe API.