Demystifying React Hooks: Inside the Core Implementation
This article explains the core implementation of React Hooks introduced in React 16.8, covering the internal Hook manager, the built‑in Hook functions such as useState, useEffect, useReducer, and provides simplified code examples to illustrate how state and side‑effects are managed within function components.
1. Introduction
React Hooks, introduced in React 16.8, allow function components to use state and other React features without class components. They provide a simpler and more understandable development experience.
2. Internal Hook Manager
The internal Hook manager is a crucial mechanism that tracks all Hooks in a component and ensures they are called in the correct order during rendering.
Example:
const Hook = {
queue: [],
current: null,
};
function useState(initialState) {
const state = Hook.current[Hook.queue.length];
if (!state) {
Hook.queue.push({
state: typeof initialState === 'function' ? initialState() : initialState,
setState(value) {
this.state = value;
render();
},
});
}
return [state.state, state.setState.bind(state)];
}
function useHook(callback) {
Hook.current = {
__proto__: Hook.current,
};
try {
callback();
} finally {
Hook.current = Hook.current.__proto__;
}
}
function render() {
useHook(() => {
const [count, setCount] = useState(0);
console.log('count:', count);
setTimeout(() => {
setCount(count + 1);
}, 1000);
});
}
render();This example shows that the Hook object has two important properties: queue stores all Hook states and update functions, and current stores the currently rendering component's Hook chain.
3. Built‑in Hook Functions
useState Hook
Implementation example:
function useState(initialState) {
const hook = updateWorkInProgressHook();
if (!hook.memoizedState) {
hook.memoizedState = [
typeof initialState === 'function' ? initialState() : initialState,
action => {
hook.queue.pending = true;
hook.queue.dispatch = action;
scheduleWork();
},
];
}
return hook.memoizedState;
}The function updateWorkInProgressHook() obtains the fiber object of the currently executing function component and determines whether a corresponding hook exists.
function updateWorkInProgressHook() {
const fiber = getWorkInProgressFiber();
let hook = fiber.memoizedState;
if (hook) {
fiber.memoizedState = hook.next;
hook.next = null;
} else {
hook = {
memoizedState: null,
queue: {
pending: null,
dispatch: null,
last: null,
},
next: null,
};
}
workInProgressHook = hook;
return hook;
} getWorkInProgressFiber()returns the fiber object of the component currently being rendered; workInProgressHook stores the current Hook object. Each useState call creates a new Hook and adds it to the fiber’s hook list.
Each Hook object also contains a queue for pending state updates, and scheduleWork() notifies React’s scheduler.
The internal implementation of useState actually calls useStateImpl:
function useStateImpl<S>(initialState: (() => S) | S): [S, Dispatch<SetStateAction<S>>] {
const dispatcher = resolveDispatcher();
return dispatcher.useState(initialState);
} resolveDispatcher()obtains the current dispatcher from the rendering fiber and throws an error if called outside a function component.
function resolveDispatcher(): Dispatcher {
const dispatcher = currentlyRenderingFiber?.dispatcher;
if (dispatcher === undefined) {
throw new Error('Hooks can only be called inside the body of a function component.');
}
return dispatcher;
}Similarly, useReducer is implemented via updateReducer (details omitted).
useEffect Hook
Implementation example:
function useEffect(callback, dependencies) {
const batch = useContext(BatchContext);
if (shouldFireEffect(batch, dependencies)) {
callback();
}
return () => clearEffect(batch);
} useEffectreceives a callback and a dependency array; when any dependency changes, React re‑executes the callback in the next render. It relies on React’s asynchronous rendering mechanism, queuing state updates and executing them after the current render batch.
The effect’s cleanup is performed via clearEffect to avoid affecting subsequent render batches.
4. Conclusion
In summary, the implementation of React Hooks is not complex; it relies on React’s internal fiber data structure and scheduling system to manage component state and lifecycle. Hooks enable function components to use state and other React features, making them as powerful as class components.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JD Cloud Developers
JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
