ログオフ
開発2026-06-06

Expo × Reactotron でデバッグ環境を整備する:expo-sqlite の静かなバグも可視化できた

console.log だけでは追いきれない Expo アプリの挙動を Reactotron で可視化した。expo-sqlite の NULL/0 型バグなど、ログに出ないバグも見つけられるようになった。

console.log だけで Expo アプリの DB 周りを追っていたら限界が来た。Reactotron を入れたら、console.log では見えなかった「型の違い」が一目で分かるようになり、放置していたバグが見つかった。この記事は、セットアップの最短手順と、実際に効いた使い方に絞る。

Reactotron で何が見えるか

Reactotron は React Native / Expo 向けのデバッグツールで、Mac/Windows のデスクトップアプリとして動く。console.log との違いは、流したオブジェクトをツリーで展開して型ごと確認できること。null0undefined と空文字のように、ターミナルだと同じに見えてしまう値の差が、画面上ではっきり分かれる。DB に何を渡して何が返ったかを追うのに向いている。

セットアップ(最短)

npm install --save-dev reactotron-react-native

reactotron-core-clientreactotron-react-native の依存として一緒に入るので、明示的に入れる必要はない。

設定ファイルを1つ作る:

// ReactotronConfig.ts
import Reactotron from 'reactotron-react-native';

if (__DEV__) {
  Reactotron
    .configure({ name: 'My App' })
    .useReactNative()
    .connect();
}

エントリポイントの先頭で読み込む:

// App.tsx
if (__DEV__) {
  require('./ReactotronConfig');
}

あとはデスクトップアプリ(releases)を起動した状態で npx expo start すれば接続される。ここまでは公式どおりで、詰まる箇所はほぼない。本題は次から。

DB 操作を Reactotron に流す

expo-sqlite のクエリ実行をラップして、渡した値と返り値をそのまま流す。これだけで INSERT / UPDATE のたびに「何を入れて何が返ったか」が画面に並ぶ。

import Reactotron from 'reactotron-react-native';
import type { SQLiteDatabase } from 'expo-sqlite';

function runQuery(db: SQLiteDatabase, sql: string, params: unknown[]) {
  const result = db.runSync(sql, params);
  if (__DEV__) {
    Reactotron.log({ sql, params, result });
  }
  return result;
}

Reactotron.log() はそのまま呼べる。オプショナルチェーン(?.)を付けたくなるが、__DEV__ で囲んで接続済みの前提なら不要だ。

これで見つかったバグ:NULL と 0 のすり替わり

入れた一番の収穫がこれだった。console.log では正常に見えていたのに、Reactotron で params を展開したら、0 を入れているつもりのカラムに null が渡っていた。undefined が混ざり込み、それが SQLite 側で null として保存されていた。

// undefined のまま渡すと null として保存される
db.runSync('UPDATE records SET count = ?', [someValue]);  // someValue が undefined のとき

// デフォルト値を明示すれば 0 が入る
db.runSync('UPDATE records SET count = ?', [someValue ?? 0]);

ターミナルだと null0 も同じ「0」に見えてしまい、型の違いに気づけない。Reactotron でツリー展開すると nullnull として表示されるので、ここで初めて差が見えた。console.log から乗り換える価値があったのは、この一点に尽きる。

補足

  • __DEV__ で囲んでいるので、設定ごと本番ビルドには入らない。
  • 実機で使う場合はアプリと PC が同じ Wi-Fi にいる必要がある。シミュレーターなら気にしなくていい。

関連記事

開発 一覧へ