Hacker News new | past | comments | ask | show | jobs | submit login

1. 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.




This would make for an interesting exercise.

  const React = /* Implement this */
  
  function HelloComponent(){
    const [myNumber, setMyNumber] = React.useState(0);
    // Simulate rendering data to a screen
    console.log("My number:", myNumber);
    // Simulate rendering a clickable button
    const click = ()=> setMyNumber((num)=> num + 1);
    return click; 
  }
  
  React.mount(HelloComponent); // prints 0
  React.simulateClick(HelloComponent); // prints 1
  React.simulateClick(HelloComponent); // prints 2
  React.simulateClick(HelloComponent); // prints 3
General idea being that the React item may be stateful, but the HelloComponent must be a stateless pure function. How can it draw on React's statefulness, while only using that useState() call?

I am working through this exercise now, but I'm already finding myself doing some pretty hacky things to make this work (like finding out who called a function using arguments.callee.caller.name). Still, it's pretty interesting.

Edit: My solution to this: https://gist.github.com/rashkov/f765917d09ebd629f385c21195f4...


Checking the function's caller breaks the composability of hooks: it stops hooks from being called by other hooks. (Also, it doesn't work in strict mode, which is enforced when you use ES modules.) React is the only thing that calls component functions, so React can just remember what component is being called before it calls it. I've posted a reply on your gist with an example that addresses this.


Very cool! appreciate the response, very interesting to see an improved solution on this.

I was mainly interested in solving for how React lines up the useState calls with the actual data that it's keeping under the hood. So I definitely cheesed through the parts touching on how React keeps track of the component tree. I'm enjoying reading through your interpretation of this though. Thanks




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: