メインコンテンツへスキップ

useDebugValue 完全入門【React】カスタムフックをDevToolsでデバッグする

ReactのuseDebugValueとは何か、カスタムフックにDevTools用ラベルを追加する方法を解説。フォーマッタ関数を使ったパフォーマンス最適化の方法も紹介します。

#react#hooks#usedebugvalue#javascript#frontend

カスタムフックを作っていると、「React DevTools でこのフックの状態を確認したい」と思うことがあります。そんなときに使えるのが useDebugValue です。

このフックは開発ツール(DevTools)向けのラベルを追加するためのもので、アプリの動作には影響しません。使う場面は限られていますが、複雑なカスタムフックを作るときに役立ちます。

この記事でわかること:

  • useDebugValue の役割と使いどころ
  • 基本的な書き方
  • フォーマッタ関数を使ったパフォーマンス最適化
  • 使うべきシーンと使わなくていいシーン
  • React DevTools で実際にどう見えるか
  • 認証・データフェッチングフックへの実践的な活用例

useDebugValue とは?

useDebugValue は、カスタムフックに React DevTools 用のラベルを追加するフックです。

useDebugValue(value);
useDebugValue(value, formatFn); // フォーマッタ関数あり
パラメータ説明
valueDevTools に表示したい任意の値
formatFn(省略可能)value を受け取りフォーマット済みの値を返す関数

戻り値はありません(undefined)。

基本的な使い方

カスタムフックの中で呼び出すだけです。

import { useState, useEffect, useDebugValue } from "react";
 
function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(true);
 
  useEffect(() => {
    const handleOnline = () => setIsOnline(true);
    const handleOffline = () => setIsOnline(false);
 
    window.addEventListener("online", handleOnline);
    window.addEventListener("offline", handleOffline);
 
    return () => {
      window.removeEventListener("online", handleOnline);
      window.removeEventListener("offline", handleOffline);
    };
  }, []);
 
  // DevTools に "Online" または "Offline" と表示される
  useDebugValue(isOnline ? "Online" : "Offline");
 
  return isOnline;
}

React DevTools でこのフックを使っているコンポーネントを確認すると、フック名の横に "Online" または "Offline" と表示されます。

React DevTools での表示確認方法

React DevTools をまだインストールしていない場合は、ChromeまたはFirefoxの拡張機能ストアから「React Developer Tools」を検索してインストールしてください。

  1. ブラウザで DevTools を開く(F12 または右クリック→「検証」)
  2. 「Components」タブを選択
  3. useDebugValue を使ったカスタムフックが含まれるコンポーネントをクリック
  4. 右パネルの「hooks」セクションに、カスタムフック名とラベルが表示される

useOnlineStatus フックなら、DevTools に次のように表示されます:

hooks
  OnlineStatus: "Online"

ラベルがないと、状態の値(true / false)だけが表示されるため、何を意味するのかパッと見でわかりにくくなります。意味のある文字列ラベルにすることで、デバッグ効率が上がります。

フォーマッタ関数で重い処理を遅延させる

DevTools が開いていないときはフォーマッタ関数の実行を避けたい場合があります。第2引数にフォーマッタ関数を渡すと、DevTools が値を表示するタイミングでのみフォーマットが実行されます。

import { useDebugValue } from "react";
 
function useLastActivity(userId) {
  const [lastActivity, setLastActivity] = useState(null);
 
  // ... データ取得ロジック ...
 
  // フォーマッタ関数:DevTools が表示するときだけ実行される
  useDebugValue(lastActivity, (date) => {
    if (!date) return "未アクティブ";
    return date.toLocaleString("ja-JP"); // 日本語形式でフォーマット
  });
 
  return lastActivity;
}

lastActivityDate オブジェクトの場合、DevTools には 2026/03/01 12:00:00 のような読みやすい形式で表示されます。

実用例1:認証フックへの活用

ログイン状態を管理するカスタムフックは、デバッグ時に「現在どのユーザーがログインしているか」をすぐ確認したい場面があります。

import { useState, useEffect, useDebugValue } from "react";
 
function useAuth() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
 
  useEffect(() => {
    // セッション確認の擬似コード
    checkSession()
      .then((userData) => setUser(userData))
      .finally(() => setLoading(false));
  }, []);
 
  // DevTools にログイン状態をわかりやすく表示
  useDebugValue(
    { user, loading },
    ({ user, loading }) => {
      if (loading) return "確認中...";
      if (!user) return "未ログイン";
      return `ログイン中: ${user.name} (${user.email})`;
    }
  );
 
  return { user, loading };
}

DevTools には "ログイン中: ぽん (example@mail.com)" のように表示され、どのアカウントでログインしているかを一目で確認できます。

実用例2:データフェッチングフックへの活用

API からデータを取得するフックでは、ローディング・エラー・成功の状態をラベルで区別できると便利です。

import { useState, useEffect, useDebugValue } from "react";
 
function useFetch(url) {
  const [state, setState] = useState({
    data: null,
    loading: true,
    error: null,
  });
 
  useEffect(() => {
    setState({ data: null, loading: true, error: null });
 
    fetch(url)
      .then((res) => res.json())
      .then((data) => setState({ data, loading: false, error: null }))
      .catch((error) => setState({ data: null, loading: false, error }));
  }, [url]);
 
  // フェッチの状態をわかりやすいラベルで表示
  useDebugValue(state, ({ loading, error, data }) => {
    if (loading) return `読み込み中: ${url}`;
    if (error) return `エラー: ${error.message}`;
    return `取得完了 (${Array.isArray(data) ? data.length + "件" : "オブジェクト"})`;
  });
 
  return state;
}

複数の useFetch を使っているコンポーネントで、どのURLのリクエストがどの状態にあるかを一目で確認できます。

実用例3:複数の値をまとめて表示

function useFormField(initialValue) {
  const [value, setValue] = useState(initialValue);
  const [isValid, setIsValid] = useState(true);
  const [isDirty, setIsDirty] = useState(false);
 
  // オブジェクトでまとめて渡すこともできる
  useDebugValue({ value, isValid, isDirty });
 
  const handleChange = (e) => {
    setValue(e.target.value);
    setIsDirty(true);
    setIsValid(e.target.value.length > 0);
  };
 
  return { value, isValid, isDirty, onChange: handleChange };
}

使うべき場面

✅ 使うべき場面
- 共有ライブラリとして公開するカスタムフック
- 状態が複雑で DevTools での確認が必要なカスタムフック
- チームで使う共通フックのデバッグ支援
- 複数の状態を持つ認証・フェッチング系フック

❌ 不要な場面
- シンプルな値を返すだけのカスタムフック
- アプリ内でしか使わない小さなフック
- すべてのカスタムフック(追加しすぎに注意)

React の公式ドキュメントでも「すべてのカスタムフックにデバッグ値を追加しないでください」と明記されています。複雑なカスタムフックに絞って使いましょう。

よくある間違いと注意点

間違い1:console.log の代わりに使う

useDebugValue は DevTools 専用です。ブラウザのコンソールには出力されません。一時的なデバッグには console.log、継続的な DevTools での確認には useDebugValue と使い分けましょう。

間違い2:フォーマッタ関数が重い処理をしている

// ❌ フォーマッタに重い処理を入れてはいけない
useDebugValue(data, (d) => {
  // 重い同期処理はNG
  return JSON.stringify(d, null, 2); // 大きなデータだと重い
});
 
// ✅ 軽い処理にとどめる
useDebugValue(data, (d) => `${d?.length ?? 0}件`);

間違い3:カスタムフック以外で使う

useDebugValue はカスタムフックの中でのみ使用してください。通常のコンポーネントで使っても意味がありません(Reactのルール的には問題ないですが、DevToolsでの表示が意図した通りになりません)。

本番環境への影響

useDebugValue本番環境(production build)では無視されます。パフォーマンスへの影響もありません。

開発中のデバッグを助けるためだけのフックなので、安心して使えます。フォーマッタ関数も本番では実行されないため、コスト面の心配も不要です。

まとめ

  • useDebugValue はカスタムフックに React DevTools 用のラベルを追加するフック
  • アプリの動作には影響せず、本番環境では無視される
  • 第2引数にフォーマッタ関数を渡すと、DevTools 表示時のみ実行される
  • 認証フック・データフェッチングフックなど状態が複雑なフックに特に有効
  • 複雑なカスタムフック・共有ライブラリ向けに絞って使う
  • すべてのカスタムフックに追加する必要はない

PR

useDebugValue 公式ドキュメントで詳細を確認しよう

useDebugValueの詳細仕様や、カスタムフックのデバッグ方法は公式ドキュメントで確認できます。

useDebugValue 公式ドキュメントを見る

PR

関連記事