What useDebugValue Does
useDebugValue(value) adds a label to a custom hook, shown next to the component in React DevTools’ component tree — purely a developer-experience aid with zero effect on the component’s actual behavior or output.
Labeling a Custom Hook
import { useState, useEffect, useDebugValue } from "react";
function useOnlineStatus() {
const [isOnline, setIsOnline] = useState(navigator.onLine);
useEffect(() => {
const handleChange = () => setIsOnline(navigator.onLine);
window.addEventListener("online", handleChange);
window.addEventListener("offline", handleChange);
return () => {
window.removeEventListener("online", handleChange);
window.removeEventListener("offline", handleChange);
};
}, []);
useDebugValue(isOnline ? "Online" : "Offline"); // shown in React DevTools
return isOnline;
}Why It’s Only Useful for Custom Hooks
Built-in hooks like useState already show their current value directly in DevTools. useDebugValue matters specifically for your own custom hooks, whose internal state would otherwise appear as an opaque, unlabeled entry in the component tree.
Deferring Expensive Formatting with a Function
If formatting the debug value is itself expensive, useDebugValue accepts an optional second argument — a formatting function — that only runs when DevTools is actually open and inspecting that component, avoiding wasted work during normal rendering.
Deferred Formatting
useDebugValue(date, (d) => d.toLocaleDateString());
// The formatting function only runs when DevTools inspects this hookHas No Effect Outside of Development
useDebugValue does nothing observable to end users — it exists purely to make custom hooks easier to inspect while developing, and has no impact on production behavior.
Best Practice
Add useDebugValue to custom hooks that are shared across a team or published as a library, where the extra clarity in DevTools helps other developers debug faster. It’s rarely necessary for simple, one-off hooks used only within a single component.