Other

useDebugValue

Displays a label for custom hooks in React DevTools. Useful for debugging complex custom hooks without adding console.log statements.

Signature

TypeScript
useDebugValue<T>(value: T, format?: (value: T) => string)

Parameters

ParameterTypeDescription
valueTThe value to display in React DevTools for this custom hook.
format(value: T) => stringOptional formatting function. Called only when the hook is inspected in DevTools, avoiding expensive formatting on every render.

Return Value

undefined — useDebugValue does not return a value.

Examples

Online Status Hook
import { useState, useEffect, useDebugValue } from 'react';

function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(navigator.onLine);

  useEffect(() => {
    const online = () => setIsOnline(true);
    const offline = () => setIsOnline(false);
    window.addEventListener('online', online);
    window.addEventListener('offline', offline);
    return () => {
      window.removeEventListener('online', online);
      window.removeEventListener('offline', offline);
    };
  }, []);

  useDebugValue(isOnline ? 'Online ✓' : 'Offline ✗');
  return isOnline;
}
Deferred Formatting
import { useDebugValue } from 'react';

function useQuery<T>(key: string) {
  const data = useFetchInternal<T>(key);

  // The format function only runs when DevTools inspects this hook
  useDebugValue(data, (d) =>
    d.status === 'loading'
      ? `Loading: ${key}`
      : d.status === 'error'
        ? `Error: ${d.error.message}`
        : `Data: ${JSON.stringify(d.value).slice(0, 50)}...`
  );

  return data;
}
Auth Hook Debug Label
import { useContext, useDebugValue } from 'react';

interface User { id: string; name: string; role: 'admin' | 'user' }

function useAuth() {
  const { user, token } = useContext(AuthContext);

  useDebugValue(user, (u) =>
    u ? `Authenticated: ${u.name} (${u.role})` : 'Not authenticated'
  );

  return { user, token, isAdmin: user?.role === 'admin' };
}

Common Pitfalls

!

Overusing useDebugValue in every hook — only add it for custom hooks where the debug label provides real insight.

!

Performing expensive formatting without the deferred format function, slowing down renders even when DevTools isn't open.

!

Using useDebugValue in components instead of custom hooks — it's designed for custom hooks only.

!

Relying on useDebugValue for production logging — it only appears in React DevTools.

Understanding useDebugValue

useDebugValue is a utility hook designed to improve the developer experience when building and using custom hooks. It lets you display a descriptive label next to your custom hook in the React DevTools component inspector. Instead of expanding hook state manually to understand what a custom hook is doing, you see a readable summary at a glance.

The hook accepts an optional format function as its second argument. This function is only called when the hook is actually being inspected in DevTools — not on every render. This lazy formatting is important for expensive operations like JSON.stringify on large objects or complex string manipulations. Without the format function, the value is displayed directly, which works fine for primitives like strings and booleans.

useDebugValue is most valuable for custom hooks that are used across many components in a codebase, such as useAuth, useTheme, useQuery, or useSocket. These hooks often encapsulate complex state that isn't immediately obvious from their return values. A debug label like "Authenticated: John (admin)" or "Loading: /api/users" provides instant insight during debugging sessions.

It's worth noting that useDebugValue has zero runtime cost in production builds — React strips DevTools integration in production mode. There's no need to conditionally include it or worry about performance in deployed applications. However, adding useDebugValue to every hook creates noise in DevTools, so reserve it for hooks where the label genuinely aids debugging. Simple hooks that just wrap useState or useRef rarely need it.

Related Hooks

More Other Hooks

Explore All React Hooks

Browse our complete reference of 19 React hooks with signatures, examples, pitfalls, and in-depth explanations.