React Easy technical 0 views 2 min read

Can you explain how useState works internally?

Peer-reviewed by HireXTech Technical Panel • Updated for 2025/2026 hiring • Editorial standards
Practise this track
Interviewer Expectations for this Question
01
Core Competency

Assesses fundamental understanding of React conventions, runtime behavior, and memory/performance considerations.

02
Evaluation Criteria

Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.

Comprehensive Model Answer Verified Solution

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,

        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];
        }
        

Candidate Response Strategy & Interview Tips

  1. Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
  2. Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
  3. Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
  4. Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.
Related Topics & Skills
Spotted an error or have an alternative solution?