InterviewHubPRO
Section Overview
Q275

Question 275 of 445

Part 9: React Hooks Deep Dive (262 - 316)

62%
React & Modern Frontend (445 Qs)•Part 9: React Hooks Deep Dive (262 - 316)

Can you explain how useState works internally?

React’s hooks, including useState, rely on some internal machinery that keeps track of state per component and per hook call during rendering. Here's a simplified explanation of the internal mechanics:

1. Hook List / Linked List

  • React maintains a linked list or array of "hook states" for each component.
  • When a component renders, React keeps track of which hook it is currently processing via a cursor/index.
  • Each call to useState() corresponds to one "slot" in this list.

2. State Storage

  • Each slot stores:
  • The current state value.
  • A queue of pending state updates.

3. Initial Render

  • When the component first renders, React:
  • Creates a new slot for useState with the initial state (e.g., 0).
  • Returns [state, updaterFunction].

4. Updater Function

  • The updater function (setCount) is a closure that, when called:
  • Enqueues a state update to React's internal queue.
  • Schedules a re-render of the component.

5. Re-render and State Update

  • On the next render:
  • React processes all queued updates for each hook slot.
  • Updates the stored state value accordingly.
  • Returns the new state to the component.

6. Important: Hook Order

  • Hooks must be called in the same order on every render so React can match hook calls to their internal slots.
  • That’s why you can’t call hooks conditionally.

The pseudocode for internal implementation of useState looks like below,

js
 let hookIndex = 0;
 const hooks = [];
 
 function useState(initialValue) {
     const currentIndex = hookIndex;
 
     if (!hooks[currentIndex]) {
         // First render: initialize state
         hooks[currentIndex] = {
             state: initialValue,
             queue: [],
         };
     }
 
     const hook = hooks[currentIndex];
 
     // Process queued updates
     hook.queue.forEach(update => {
         hook.state = update(hook.state);
     });
     hook.queue = [];
 
     // Define updater function
     function setState(action) {
         // action can be new state or function(state) => new state
         hook.queue.push(typeof action === 'function' ? action : () => action);
         scheduleRender(); // triggers React re-render
     }
 
     hookIndex++;
     return [hook.state, setState];
 }