How React DevTools Peeks Inside Components and Extends useDebugValue
This article explains the inner workings of React DevTools, how it hooks into ReactDOM to access FiberNode structures and component data, and demonstrates a custom useDebugValueAnywhere implementation that bypasses the original hook's limitations for advanced debugging.
Introduction
Developers familiar with React often use React DevTools, which can display the component tree, props, and hook values. This article explains how DevTools detects a React page and extracts component data.
How React DevTools Works
Searching the ReactDOM source for the keyword devtools reveals the hook injection code. By inspecting the global object __REACT_DEVTOOLS_GLOBAL_HOOK__ in the console, we can see its methods such as onCommitFiberRoot, onCommitFiberUnmount, and onPostCommitFiberRoot, which are invoked during rendering.
Render Phase
During rendering, React calls methods like onCommitFiberRoot. The global hook links React DevTools with ReactDOM, allowing the tool to retrieve component information.
function onCommitRoot(root, priorityLevel) {
if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
try {
injectedHook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
} catch (err) {}
}
}FiberRoot and FiberNode
In the new React architecture, the virtual DOM is first converted into FiberNode objects, which are then rendered. Methods like onCommitFiberRoot receive a FiberNode that contains fields such as stateNode (the real DOM node), memoizedProps (props), and memoizedState (hooks or state). The FiberNode forms a linked‑list structure.
Traversing FiberNode to Find DOM Nodes
By locating the FiberNode of a component, DevTools can non‑intrusively obtain its information, for example using findNativeNodesForFiber to retrieve the corresponding DOM element.
function findNativeNodesForFiber(node?: ReactFiberNode) {
// ... traverse child
const { child } = node;
collectStateNode();
// ... traverse siblings
let current = child?.sibling;
while (current) {
collectStateNode();
current = current.sibling;
}
// ...
}Practical Example: Extending useDebugValue
The built‑in useDebugValue hook can only be called inside other hooks. By leveraging the internal hook data exposed through the global hook, we can implement useDebugValueAnywhere, which works like a normal hook without the original limitation.
export function useDebugValueAnywhere(name: string, data: any) {
const ref = useRef({
[DebugHookKey]: {
name,
data,
},
});
// ...
}Injecting Custom Logic into DevTools
We inject our own onCommitFiberRoot implementation into __REACT_DEVTOOLS_GLOBAL_HOOK__ so that each ReactDOM render provides the latest FiberNode. Traversing the FiberNode chain and inspecting memoizedState lets us detect usage of useDebugValueAnywhere and collect its debug data.
visitFiberNode(node?: ReactFiberNode) {
if (!node) return;
this.inspectFiber(node);
this.visitFiberNode(node.child);
let { sibling } = node;
while (sibling) {
this.visitFiberNode(sibling);
sibling = sibling.sibling;
}
}Collected debug information can be displayed in the console on desktop or via a vConsole plugin on mobile, effectively creating a lightweight React DevTools.
Conclusion
This article dissected the inner workings of React DevTools, introduced hidden ReactDOM features, and walked through the React Fiber architecture. Using these insights, we built an enhanced useDebugValue implementation. Because the techniques rely on undocumented APIs, they may break with future React releases and are intended for tool development rather than production code.
References
React DevTools: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi ReactDOM source: https://cdn.jsdelivr.net/npm/[email protected]/umd/react-dom.development.js useDebugValue docs: https://zh-hans.reactjs.org/docs/hooks-reference.html#usedebugvalue Full source code: https://github.com/ziyoung/react-dom-render-hook/blob/master/src/sdk/install.ts
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.
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.
