How react hooks work?

Neeraj Vageele

Sep 17, 2020 | 3 min read

React Hooks are introduced in version 16.8 released in February 2019. Hooks are API's or in-built functions introduced to use state and other features in React without writing a class. If you want to get started with React or React Hooks, here is official React documentation. In official documentation it only explains usage for react hooks, so we will learn about the working of hooks.

React hooks

Prerequisites

  • Should know JavaScript and React

Before understanding the working of hooks let's take a quick look at the types of hooks react provide.

Basic React Hooks

10 in-built hooks were shipped with React 16.8 but the basic (commonly used) hooks include:

Basic Hooks

Additional Hooks

Now let us understand how hooks work under the hood with the help of an example.

const Counter = () => {
  const [counter, setCounter] = useState(0);
  onClick = () => setCounter(prev => prev + 1);
  return (
    <button onClick={onClick}>Click me</button>
    <p>{[counter}}</p>
  )
}

We have created a function with the name "Counter" which returns the button and counter value in view.

const [counter, setCounter] = useState();

Here we are using the useState hook which returns a current state value and a function to update current state value. Below is an example of the implementation of the useState hook function.

let context = {};
// we will use this callId to persist the state for useState call
let callId = -1;

function render(Component) {
  // store the Component function to the context
  context.Component = Component;
  // invoke the Component function
  const instance = Component();
  // render the Component  
  instance.render();
  // reset the callId after every render
  callId = -1;
  // add the instance to the context and retrun the context
  // so that we can invoke the other method of the instance
  // like so:
  // const context = render(Component);
  // context.instance.someInstanceMethod();
  context.instance = instance;
  return context;
}

function useState(initialState) {
    if (!context) {
      throw new Error('hooks can not be called with out a rendering context');    
    }
    if (!context.hooks) {
      context.hooks = [];
    }
    
    callId = callId + 1;
    
    const hooks = context.hooks;
    const currentState = hooks[callId] ? hooks[callId] : initialState;
    hooks[callId] = currentState;
    const setState = function () {
      const currentCallId = callId;
      return function (newState) {
        hooks[currentCallId] = newState;
        render(context.Component);  
      }
    }();  
  
    return [currentState, setState];
 }
Sample useState function

Note: This is not an exact implementation of useState that is in the original React code.

In the above sample, we have a global context in which we have a component instance in context so we can access components in useState function, as we are calling useState directly from our custom components. In react for a component, it is compulsory to return something, mostly view. So in this functional approach, we do not have a render method but we return view. After compiling this function, react makes components from this function and puts this view in the render function.

When the initial render is called with component instance, it is saved in context. Whenever the setState function is called, it updates the current value and calls the render function with the context component.

This is how the render method is called on every state update and we get updated value in view. For more detailed explanations refer to this blog.

onClick = () => setCounter(prev => prev + 1);

In this onClick function, we have triggered the setCounter function to update the counter value.

return (
    <button onClick={onClick}>Click me</button>
    <p>{[counter}}</p>
)

When we click on the button it triggers the setCounter function which will update the counter value and in return, it triggers the render method and update value in view.

Graphical representation

In the above explanation, we learn about the useState hook only, using a similar approach we can understand other hooks also, but there might be other things also to consider and understand like closure to properly understand its working.

References:
https://medium.com/swlh/how-does-react-hooks-re-renders-a-function-component-cc9b531ae7f0
https://www.netlify.com/blog/2019/03/11/deep-dive-how-do-react-hooks-really-work/#:~:text= Deep dive%3A How do React hooks really,can go. You can try implementing... More