4 ms·
Ok, quick test: can you explain in a paragraph why you cannot call a hook inside a for loop?
by ricardobeat 6y ago
Ok, quick test: can you explain in a paragraph why you cannot call a hook inside a for loop?
- cnity 6y agoSo easy I can explain it in a sentence: React hooks must always be called in the same order, and the same amount. If you push me by asking "why?", I can expand that sentence by including "because each hook call is associated with an index under the hood". This is probably the only React hook nuance you really have to understand, and it's not particularly difficult.
- ricardobeat 6y agoWhich means you can call it inside a for loop if you have guarantees that the order will always be the same. These are the caveats that don't fit in one paragraph. Also, repeating the rule 'it has to be called in the same order' is not explaining how it works.
- cnity 6y agoWhat makes the fact that each hook call needs to be associated with an index so unacceptable?
- ricardobeat 6y agoYou could say each call corresponds to a timestamp and they need to be ordered, and the person receiving that information would be none the wiser. It just doesn't lead you to understand what's happening underneath. Some may be fine with stopping at that level of understanding, but the stack-based approach of hooks is quite unnatural for JS and I don't think it is good in the long-term for developers to just 'accept' that as supernatural.
- cnity 6y agoSo in order to understand not only the basics of the rule, but also the underlying implementation and exactly in what way it would crash, it may require more than a paragraph. I'll concede that. But this is common in programming. As an example, you'd probably spend some time understanding exactly why it is you can't free a pointer twice in C. There's nothing stopping someone from reading the explanation in the React docs[0] if they want to understand. [0] https://reactjs.org/docs/hooks-rules.html#explanation https://reactjs.org/docs/hooks-rules.html#explanation
- ricardobeat 6y ago> This is probably the only React hook nuance you really have to understand Absolutely not. There is the dependencies array, how it only does a strict equals check (no shallow comparison), how you need to memoize other dependencies so they don't change on every render, why it is a problem to leave it empty, why useEffect cannot strictly replace componentDidMount, why you can't put one hook inside the other, how (and which) hooks can trigger a re-render or block updates, how state is captured by the closure and what to do if you need current state, how to persist things across renders using useRef.. and probably more.
- cnity 6y agoI personally find these quite easy to comprehend, but I suppose I can see how it might be difficult. Edit: That was snarky, I apologise.
- sydd 6y agoSomething that I still don't grasp with React: 1. Your render function runs quite often, e.g. on each state change. 2. But it runs a bit differently sometimes: const [a,setA] = useState(1234); Here "a" will have the value 1234 on the first run (what is a first run? When react instantiates this component? When it mounts?) Then this same line of code will assign a different value to this same variable, because setA was called in the past. Why? How does it know that this exact local variable needs a different value?
- 7786655 6y ago1. When React mounts your component, it creates an object to contain its internal state, including the state of all hooks. 2. Before calling your render function, it stores a reference to that object in a private, global variable. (Global in the sense that there's only one per JS VM) (Javascript is single-threaded so this is perfectly safe to do). 3. Each of the built-in hooks has access to that variable, and use it to increment a number representing the current hook index and then store information in an array at the current index. 4. The next time your component is rendered, that information is still there and the hooks can retrieve it. 5. Also some hooks like useEffect set up functions to be called by react later.
- j-krieger 6y agoYes! A hook call occurs at most once per render. For react to figure out which hook call corresponds to what state, it analyzes the call order. Because we write component render functions top down, the hook call order stays the same every time every render. Not so if we call a hook inside a loop [1]. Why would you call a hook inside a loop anyway? Hooks return callbacks and variables, which you can use inside a loop without problem. [1]: https://reactjs.org/docs/hooks-rules.html#explanation https://reactjs.org/docs/hooks-rules.html#explanation
- beirut_bootleg 6y agoJust as you don't call this.componentDidUpdate in a loop. I'm reading through the comments and trying to figure out what mental model some have of React that causes them to just don't "get" hooks. I'm starting to think this difference in thinking did not start with hooks.
- tuesdayrain 6y agoHooks aren't always comparable to lifecycle methods. At my company every GraphQL query/mutation has a corresponding hook. There are frequently times when devs are tempted to use them, especially the mutations, in for loops.
- franciscop 6y agoBecause React keeps track of the hooks you are using by the call order, and a loop might indicate than in different rerenders it might have different lengths. You actually can do it, it's just the linter trying to avoid you shooting yourself in the foot. In fact the linter explains exactly that in a paragraph: > React Hook "useState" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render. https://reactjs.org/docs/hooks-rules.html https://reactjs.org/docs/hooks-rules.html
- ricardobeat 6y agoThat was close :) See my replies below for a counterpoint.