React Nativeでモバイルアプリを開発していると、「JavaScriptレイヤーで起きたバグなのか、ネイティブ側の問題なのか切り分けられない」という壁にぶつかることがあります。Webアプリと異なり、iOSとAndroidの両プラットフォームにまたがるデバッグは独特の難しさを持っています。
2024年にFlipperが標準構成から外れ、代わりにReact Native DevToolsが公式デバッガとして整備されたことで、デバッグのワークフロー自体が大きく刷新されました。従来の情報のまま開発を続けていると、非推奨のツールに時間を費やしてしまう可能性があります。
ここでは、2026年2月時点の最新環境(React Native 0.84 / Hermes V1)を前提に、基本のログ出力から高度なパフォーマンス解析まで、実務で使えるデバッグ手法を体系的に整理します。
Flipper廃止からReact Native DevToolsへの移行経緯
React Native 0.73(2023年12月リリース)で、従来標準だったFlipperのネイティブ統合が非推奨となりました。0.74以降で新規プロジェクトにはFlipperがインストールされなくなり、0.76でReact Native DevToolsが正式に利用可能になっています。
移行の背景には、以下の技術的な事情があります。
- FlipperはElectronベースの独立アプリとして動作しており、起動の遅さやメモリ消費が開発者から課題として指摘されていた
- HermesエンジンがデフォルトJSエンジンとなったことで、Chrome DevToolsプロトコル(CDP)との直接接続が可能になった
- ゼロインストールでブラウザから即座に接続できる体験が実現できるようになった
現在のReact Native 0.84ではHermes V1がデフォルト化され、React Native DevToolsのNetwork・Performanceパネルも0.83で追加されています。Flipperでしかできなかった機能がほぼ公式ツールでカバーされた形です。
| バージョン | デバッグ環境の変更 |
|---|---|
| 0.73(2023年12月) | Flipperネイティブ統合を非推奨化、新デバッガのTechnical Preview公開 |
| 0.74(2024年4月) | 新規プロジェクトからFlipper削除 |
| 0.76(2024年10月) | React Native DevTools正式利用可能、New Architectureデフォルト化 |
| 0.79(2025年4月) | Remote JS Debugging(Chrome経由のリモートデバッグ)を完全削除 |
| 0.83(2025年12月) | Networkパネル・Performanceパネル追加、DevToolsデスクトップアプリ提供開始 |
| 0.84(2026年2月) | Hermes V1デフォルト化、Legacy Architecture削除推進 |
なお、FlipperのGitHubリポジトリ(facebook/flipper)は2025年9月にアーカイブ化(読み取り専用)されており、今後の開発は行われません。
標準搭載のデバッグ機能
React Nativeにはビルトインで複数のデバッグ機能が組み込まれています。外部ツールを導入する前に、まずこれらを使いこなすことが効率的なデバッグの第一歩です。
Dev Menu(開発者メニュー)
Dev Menuは各種デバッグ機能へのエントリポイントです。以下のショートカットで呼び出せます。
| 環境 | 操作 |
|---|---|
| iOSシミュレータ | Ctrl + Cmd + Z または Device → Shake |
| Androidエミュレータ(macOS) | Cmd + M |
| Androidエミュレータ(Windows/Linux) | Ctrl + M |
| Android実機(adb経由) | adb shell input keyevent 82 |
| 物理デバイス共通 | 端末をシェイク |
Dev Menuから利用できる主な機能は以下の通りです。
- Open DevTools — React Native DevToolsを起動
- Reload — JavaScriptバンドルを再読み込み
- Fast Refresh — コード変更の即時反映ON/OFF
- Perf Monitor — FPSやメモリ使用量のオーバーレイ表示
- Element Inspector — UI要素のプロパティ確認
React Native DevTools
React Native DevToolsは0.76以降で利用できる公式デバッガです。Chrome DevToolsをベースにReact Native専用のカスタマイズが施されており、ブラウザ上で動作します。
起動方法:
- Dev Menuから「Open DevTools」を選択
- Metro CLIで
jキーを押下
搭載パネルと機能一覧:
| パネル | 対応バージョン | 主な用途 |
|---|---|---|
| Console | 0.76〜 | ログ閲覧、JS式の評価、Live Expressions |
| Sources | 0.76〜 | ブレークポイント設定、ステップ実行、コールスタック確認 |
| React Components | 0.76〜 | コンポーネントツリー表示、Props/Stateの閲覧・編集 |
| React Profiler | 0.76〜 | コンポーネントレンダリング時間の計測 |
| Network | 0.83〜 | HTTP通信の監視(fetch/XMLHttpRequest/Image) |
| Performance | 0.83〜 | JS実行時間・レンダリング・ネットワークのタイムライン |
| Memory | 0.76〜 | ヒープスナップショット、メモリリーク検出 |
Web開発でChrome DevToolsに慣れている方であれば、ほぼ同じ操作感でReact Nativeアプリのデバッグが可能です。
LogBox
LogBoxはアプリ内でエラーや警告を視覚的に表示する仕組みです。React Native DevToolsが開いている場合、致命的エラー以外はDevTools側に集約されます。
致命的エラー(Fatal Error): 構文エラーなど回復不能な状態で全画面表示されます。Fast Refreshまたは手動リロードで解消します。
コンソールエラー: 赤いバッジで通知カウントが表示されます。タップすると詳細のスタックトレースを確認できます。
警告: 黄色いバナーで表示されます。
ノイズの多い警告をフィルタリングしたい場合は、LogBox.ignoreLogs で制御できます。
import { LogBox } from 'react-native';
// 文字列の部分一致または正規表現でフィルタリング
LogBox.ignoreLogs([
'Warning: componentWillReceiveProps has been renamed',
/GraphQL error: .*/,
]);
本番デモ時にすべてのログを非表示にするには LogBox.ignoreAllLogs() を使います。ただし、開発中にこの設定を有効にしたまま忘れると、重要な警告を見逃す原因になるため注意が必要です。
console.logを超えるログ戦略
console.log はもっとも手軽なデバッグ手段ですが、大規模プロジェクトではログが溢れて必要な情報を見つけにくくなります。以下の方法を組み合わせることで、ログの視認性と管理性が向上します。
console APIの使い分け
// 通常のデバッグ情報
console.log('ユーザーデータ取得完了', userData);
// 警告レベル(黄色表示)
console.warn('APIレスポンスにdeprecatedフィールドが含まれています');
// エラーレベル(赤色表示、スタックトレース付き)
console.error('認証トークンの更新に失敗しました', error);
// オブジェクト構造をテーブル形式で表示
console.table(apiResponses);
// 処理時間の計測
console.time('データフェッチ');
await fetchData();
console.timeEnd('データフェッチ'); // → "データフェッチ: 245.123ms"
// 条件付きログ(条件がfalseの場合のみ出力)
console.assert(items.length > 0, 'アイテムリストが空です');
debuggerステートメントによる即時ブレーク
コード中に debugger; と記述すると、React Native DevToolsが接続されている状態でその行に到達した瞬間に実行が一時停止します。
const handlePayment = async (amount) => {
debugger; // ここで一時停止し、amountの値をScopesパネルで確認
const result = await paymentAPI.charge(amount);
return result;
};
ブレークポイントをDevToolsのUIから設定する方法と比べて、条件分岐の奥深くなど特定のコードパスに到達した場合のみ止めたい場面で有効です。
本番ビルドでのログ除去
リリースビルドにconsole.logが含まれるとパフォーマンスに影響するため、Babelプラグインで除去するのが一般的です。
// babel.config.js
module.exports = {
presets: ['module:@react-native/babel-preset'],
env: {
production: {
plugins: ['transform-remove-console'],
},
},
};
babel-plugin-transform-remove-console をインストールすることで、本番ビルド時に自動的にすべてのconsole呼び出しが削除されます。
ブレークポイントを活用した効率的なバグ特定
ログを大量に仕込むよりも、ブレークポイントで実行を止めて変数の状態を調べるほうが、複雑なバグの原因を素早く突き止められます。
React Native DevToolsでのブレークポイント操作
- DevToolsのSourcesパネルを開く
Cmd + P(macOS)/Ctrl + P(Windows/Linux)でファイル検索- 対象ファイルを開き、行番号をクリックしてブレークポイントを設置
- アプリで該当処理を実行すると、その行で実行が一時停止
- 右パネルのScopesでローカル変数・クロージャ変数の値を確認
- Call Stackで呼び出し元を追跡
条件付きブレークポイントも設定可能です。行番号を右クリックして「Add conditional breakpoint」を選び、userId === 'test-user' のような条件式を入力すると、条件に合致した場合のみ一時停止します。
ログポイントはブレークポイントの派生機能で、実行を止めずにコンソールへメッセージを出力します。行番号を右クリックして「Add logpoint」を選択し、'Request payload:', JSON.stringify(payload) のような式を指定します。
VSCodeからのリモートデバッグ
VSCodeで直接ブレークポイントを設定してデバッグしたい場合は、Microsoft製の「React Native Tools」拡張機能を利用します。
セットアップ手順:
- VSCodeの拡張機能から「React Native Tools」(msjsdiag.vscode-react-native)をインストール
- プロジェクトルートに
.vscode/launch.jsonを作成
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to packager",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "attach"
},
{
"name": "Debug iOS",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "launch",
"platform": "ios"
},
{
"name": "Debug Android",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "launch",
"platform": "android"
}
]
}
- Metroバンドラーを起動した状態で、VSCodeのデバッグパネルから構成を選択して実行
- エディタ上でブレークポイントを設置し、アプリ操作でヒットさせる
エディタとデバッガが統合されているため、コードの修正とデバッグを同じ画面で完結できるのがメリットです。
ネットワーク通信のトラブルシューティング
API通信のデバッグは、モバイルアプリ開発で最も頻繁に必要になる作業の一つです。
React Native DevToolsのNetworkパネル(0.83以降)
0.83で追加されたNetworkパネルは、fetch()・XMLHttpRequest・<Image>コンポーネントの通信を自動的にキャプチャします。
確認できる情報は以下の通りです。
- リクエスト/レスポンスのヘッダ
- レスポンスボディのプレビュー
- タイミング情報(DNS解決〜レスポンス完了まで)
- リクエスト発行元のコールスタック(Initiatorタブ)
Initiatorタブでリクエストがどのコンポーネント・関数から発行されたかを追跡できるため、「どのAPI呼び出しが意図しないタイミングで実行されているか」を特定する際に役立ちます。
制限事項: WebSocket通信のキャプチャ、レスポンスのモック、ネットワークスロットリングには対応していません(2026年2月時点)。
0.82以前の環境でのネットワークデバッグ
React Native DevToolsのNetworkパネルが使えないバージョンでは、以下の方法で代替できます。
グローバルfetchのインターセプト:
// App.jsの先頭に記述(開発時のみ)
if (__DEV__) {
const originalFetch = global.fetch;
global.fetch = async (...args) => {
const [url, options] = args;
console.log('[FETCH]', options?.method || 'GET', url);
const start = Date.now();
try {
const response = await originalFetch(...args);
console.log('[FETCH] Status:', response.status, `(${Date.now() - start}ms)`);
return response;
} catch (error) {
console.error('[FETCH] Error:', error.message);
throw error;
}
};
}
Reactotronの活用:
Reactotron(後述)にはNetworkインスペクタが搭載されており、HTTP通信のリクエスト/レスポンスをGUIで確認できます。DevToolsのNetworkパネルが使えない環境では有力な選択肢です。
パフォーマンスの計測と改善
アプリの動作が遅い場合、原因がJavaScript側にあるのかネイティブ側にあるのかを切り分けることが重要です。
Performance Monitorでの概観
Dev Menuから「Perf Monitor」を有効にすると、画面上部にオーバーレイが表示されます。
- JS Thread FPS — JavaScriptスレッドのフレームレート。ここが低い場合はJSの処理負荷が高い
- UI Thread FPS — ネイティブUI描画のフレームレート。ここが低い場合はネイティブ側のレンダリングが重い
- RAM使用量 — アプリが消費しているメモリ量
この数値はあくまで目安であり、正確なプロファイリングにはDevToolsのPerformanceパネルやネイティブIDEのツールを使用します。
React Native DevToolsのPerformanceパネル(0.83以降)
JavaScript実行時間、Reactのレンダリング、ネットワークイベントをタイムラインで可視化できます。
User Timings APIを使ったカスタム計測:
// 画面遷移の所要時間を計測
performance.mark('navigation-start');
// ...画面遷移処理...
performance.mark('navigation-end');
performance.measure('画面遷移時間', 'navigation-start', 'navigation-end');
この計測結果はPerformanceパネルのタイムラインに表示されるため、どの処理がボトルネックなのかを視覚的に把握できます。
React Profilerでレンダリング最適化
React Native DevToolsのReact Profilerタブでは、各コンポーネントのレンダリング回数と所要時間を記録できます。
- Profilerタブの録画ボタンをクリック
- アプリを操作
- 録画を停止
- フレームグラフで各コンポーネントのレンダリングコストを確認
不要な再レンダリングを検出するには、React Components パネルの設定(⚙ アイコン)から「Highlight updates when components render」を有効にします。画面上でレンダリングが発生したコンポーネントがハイライトされるため、React.memo や useMemo を適用すべき箇所を視覚的に特定できます。
ネイティブレイヤーの調査
React Native DevToolsで解決できない問題、たとえばネイティブモジュールのクラッシュやプラットフォーム固有のUI不具合は、各OSの開発ツールで調査する必要があります。
Xcodeを使ったiOSデバッグ
- ブレークポイント: Objective-C/SwiftレイヤーにブレークポイントをXcode上で直接設定可能
- Instrumentsプロファイラ: CPU使用率、メモリリーク、ディスクI/O、ネットワーク通信をネイティブレベルで計測
- コンソールログ: ネイティブ側の
NSLog出力を確認 - View Hierarchy Debugger: ネイティブビューの階層構造を3Dで可視化
Android Studioを使ったAndroidデバッグ
- Logcat: ネイティブ側のログをリアルタイムでフィルタリング表示
- Layout Inspector: ビュー階層とプロパティの確認
- Android Profiler: CPU、メモリ、ネットワーク、エネルギー消費を時系列で可視化
- ブレークポイント: Java/Kotlinレイヤーのステップ実行
JavaScriptとネイティブの境界で発生する問題(例: ネイティブモジュールのブリッジ経由のデータ受け渡しエラー)は、両方のデバッガを同時に起動して切り分けると効率的です。
サードパーティ製デバッグツール
標準ツールに加えて、特定の用途に特化したサードパーティ製ツールを併用すると生産性が向上します。
Reactotron
Infinite Red社が開発するオープンソースのデスクトップアプリケーションです。macOS・Windows・Linuxに対応しており、React NativeアプリとTCP接続して各種データを可視化します。
主要機能:
- API通信のリクエスト/レスポンス表示(ヘッダ・ボディ・レスポンス時間)
- Redux/MobX/Zustandなどの状態管理ライブラリとの連携(アクション・状態変更のタイムライン表示)
- AsyncStorage・MMKVの内容確認
- カスタムコマンドの送信
- パフォーマンスベンチマーク
本番ビルドには一切のコードが含まれないため、デバッグ用コードがリリースに混入するリスクがありません。
公式リポジトリ: https://github.com/infinitered/reactotron
Sentryによるクラッシュ監視
開発中のデバッグだけでなく、本番環境で発生したクラッシュやエラーを追跡するためにはクラッシュ監視サービスの導入が有効です。
Sentryは、JavaScriptレイヤーの例外だけでなく、ネイティブ側のクラッシュ(iOSのNSException、AndroidのJava例外)も統合的に収集します。
# Sentry React Native SDKのインストール
npx @sentry/wizard@latest -i reactNative
import * as Sentry from '@sentry/react-native';
Sentry.init({
dsn: 'https://your-dsn@sentry.io/project-id',
tracesSampleRate: 1.0,
});
導入後はクラッシュレポートにスタックトレース・デバイス情報・ユーザー操作の再現ステップが自動で付与されるため、本番環境固有の問題を効率的に調査できます。
公式ドキュメント: https://docs.sentry.io/platforms/react-native/
Redux DevToolsとの統合
ReduxやRedux Toolkitを使っている場合、React Native DevToolsのReact Profilerと組み合わせてステート変更を追跡できます。Reactotronとの連携も可能で、アクションのディスパッチ履歴と状態のdiffをタイムライン上で確認できます。
Expo環境固有のデバッグ
ExpoはReact Nativeの上に構築された開発プラットフォームで、独自のデバッグ機能を提供しています。
- Expo CLI(
npx expo start)からのDevTools起動: Metro CLIと同様にjキーでReact Native DevToolsを起動 - expo-dev-client: カスタムネイティブモジュールを含むExpoプロジェクトでの開発ビルド。Dev Menuの拡張版が利用可能
- Expo DevToolsのNetworkパネル: Expo独自のフェッチ実装(Expo Fetch)もキャプチャ対象に含まれる
Expoのmanaged workflowでは、ネイティブコードに直接触れないためXcode/Android Studioによるデバッグが不要な場面が多く、React Native DevToolsだけで完結するケースが大半です。
デバッグツール比較一覧
| ツール | カテゴリ | 対応範囲 | コスト | 主な用途 |
|---|---|---|---|---|
| React Native DevTools | 公式組込 | JS/React | 無料 | コンソール、ブレークポイント、ネットワーク、パフォーマンス |
| Performance Monitor | 公式組込 | FPS/メモリ概観 | 無料 | 簡易パフォーマンスチェック |
| LogBox | 公式組込 | エラー/警告 | 無料 | アプリ内エラー表示 |
| VSCode React Native Tools | 拡張機能 | JS | 無料 | エディタ統合デバッグ |
| Reactotron | デスクトップアプリ | JS/ストレージ/通信 | 無料(OSS) | 状態管理・API通信の可視化 |
| Xcode Instruments | IDE同梱 | ネイティブ(iOS) | 無料 | iOS固有のプロファイリング |
| Android Profiler | IDE同梱 | ネイティブ(Android) | 無料 | Android固有のプロファイリング |
| Sentry | SaaS | JS/ネイティブ | フリープランあり | 本番クラッシュ監視・エラー追跡 |
よくあるエラーと対処法
Metro Bundlerの接続エラー
Unable to load script. Make sure you're either running Metro or that your bundle is packaged correctly.
対処:
npx react-native start --reset-cacheでMetroキャッシュをクリア- Android実機の場合は
adb reverse tcp:8081 tcp:8081でポートフォワーディング - ファイアウォールが8081ポートをブロックしていないか確認
Red Screen of Death(赤画面)
JavaScriptの実行時エラーで全画面赤表示になった場合は以下を確認します。
- スタックトレースの最上部に表示されるファイル名と行番号を確認
undefined is not an object→ 未初期化の変数やPropsへのアクセスCannot read property 'xxx' of null→ APIレスポンスがnullの場合のガード漏れInvariant Violation→ Reactコンポーネントのライフサイクルに関する制約違反
Hermesエンジン固有の注意点
Hermes V1がデフォルトとなった0.84以降では、以下の点に留意が必要です。
Dateオブジェクトの一部メソッド(toLocaleStringなど)のロケール対応が限定的。国際化にはIntlポリフィル(intl-pluralrules等)を併用eval()はセキュリティとパフォーマンス上の理由でデフォルト無効。必要な場合はHermesのビルド設定で有効化- ソースマップが正しく設定されていないとスタックトレースの行番号がズレるため、
metro.config.jsのsourceMaps設定を確認
まとめ
React Nativeのデバッグは、Flipperの廃止とReact Native DevToolsの登場により、2024年以降シンプルかつ強力になっています。効率的にバグを解決するためのポイントを整理します。
- 第一選択はReact Native DevTools。 0.76以降ならゼロインストールでブラウザからConsole・Sources・React Components・Profilerを使え、0.83以降はNetwork・Performanceも利用可能
- console.logは最低限に。 ブレークポイントやLogBox、User Timings APIなど目的に適したツールを選ぶ
- ネイティブ問題はネイティブIDEで。 XcodeとAndroid Studioは、JSレイヤーでは見えないクラッシュやパフォーマンスボトルネックの調査に不可欠
- 本番環境にはSentryなどのクラッシュ監視を導入。 開発時には再現できない問題を、リアルユーザーの環境から自動収集
各ツールのドキュメントへのリンクを以下にまとめます。
