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.

Huolala Tech
Huolala Tech
Huolala Tech
How React DevTools Peeks Inside Components and Extends useDebugValue

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

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendReactDevToolsFiberuseDebugValue
Huolala Tech
Written by

Huolala Tech

Technology reshapes logistics

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.