RORK LABEN
PLAY — Google Play の target API level 36 要件が昨日8月31日に発効しました。今日以降、新規アプリと既存アプリの更新は Android 16 対応が必須ですVISIBILITY — API 35 のままのアプリは掲載こそ続きますが、新しい Android 版のユーザーには表示されなくなります。エラーが出ないまま新規インストールだけが減る点に注意が要りますEXTENSION — 間に合わなかった場合は、Play Console から2026年11月1日までの延長申請が出せます。恒久対応の計画とセットで進めるのが実務的ですAPPLE — Apple 側は9月9日にイベント、iOS 27 の正式リリースは9月14日と報じられています。生成したアプリの iOS 27 実機確認はリリース週の前に済ませておきたいところですEXPO — Expo が expo-paste-input を公開しました(8月28日)。React Native の TextInput に画像・GIF・ステッカーの貼り付けを追加するネイティブモジュールですEAS — EAS Observe が8月20日に GA になりました。クラッシュや性能の観測を、ビルドや配信と同じ EAS 上で持てるようになっていますPLAY — Google Play の target API level 36 要件が昨日8月31日に発効しました。今日以降、新規アプリと既存アプリの更新は Android 16 対応が必須ですVISIBILITY — API 35 のままのアプリは掲載こそ続きますが、新しい Android 版のユーザーには表示されなくなります。エラーが出ないまま新規インストールだけが減る点に注意が要りますEXTENSION — 間に合わなかった場合は、Play Console から2026年11月1日までの延長申請が出せます。恒久対応の計画とセットで進めるのが実務的ですAPPLE — Apple 側は9月9日にイベント、iOS 27 の正式リリースは9月14日と報じられています。生成したアプリの iOS 27 実機確認はリリース週の前に済ませておきたいところですEXPO — Expo が expo-paste-input を公開しました(8月28日)。React Native の TextInput に画像・GIF・ステッカーの貼り付けを追加するネイティブモジュールですEAS — EAS Observe が8月20日に GA になりました。クラッシュや性能の観測を、ビルドや配信と同じ EAS 上で持てるようになっています
記事一覧/開発ツール
開発ツール/2026-03-30中級

Rork で出る React Native / Expo ランタイムエラーを切り分けて直す

Rork が生成する React Native + Expo ベースのアプリで発生する典型的なランタイムエラーの完全な解決ガイド。TypeError、Hooks ルール違反、モジュール互換性問題を実例とコード例で解説。

React Native233Expo192ランタイムエラーtroubleshooting26

Rork アプリが React Native / Expo ベースである理由

Rork が生成するモバイルアプリは、内部的に React Native + Expo で構築されています。このため、React Native 固有のランタイムエラーが発生することがあります。これらのエラーは一度理解すれば、以降のアプリ開発で繰り返し遭遇する同じパターンなので、今のうちに解決方法を習得しておく点が肝心です。


よくあるランタイムエラー TOP 5

1. TypeError: undefined is not an object

症状: アプリが起動直後にクラッシュし、コンソールに TypeError: undefined is not an object と表示されます。

原因: State(状態)の初期化を忘れているケースが大半です。

// ❌ 間違い: state の初期値がない
import { useState } from "react";
import { View, Text, FlatList } from "react-native";
 
export default function ProductList() {
  const [products, setProducts] = useState(); // undefined として初期化される
 
  return (
    <FlatList
      data={products}  // undefined.map() を呼ぼうとしてエラーになる
      renderItem={({ item }) => <Text>{item.name}</Text>}
      keyExtractor={(item) => item.id}
    />
  );
}
 
// ✅ 正しい: 空配列で初期化
export default function ProductList() {
  const [products, setProducts] = useState([]); // 空配列で初期化
 
  return (
    <FlatList
      data={products}  // 安全に反復できる
      renderItem={({ item }) => <Text>{item.name}</Text>}
      keyExtractor={(item) => item.id}
    />
  );
}

解決方法:

  • useState(undefined) ではなく、適切な初期値(空配列 []、デフォルトオブジェクト {}、など)を指定する
  • データ取得完了まで UI を条件付きレンダリングする(if (!data) return <Loading />

2. Invariant Violation: Text strings must be rendered within a component

症状: コンソールに Invariant Violation: Text strings must be rendered within a <Text> component と表示され、赤い画面が出現します。

原因: React Native では、**テキスト文字列を直接 <View> に入れることができません。**すべてのテキストは <Text> コンポーネントでラップする必要があります。

// ❌ 間違い: テキストが <Text> にラップされていない
import { View } from "react-native";
 
export default function App() {
  return (
    <View>
      Hello World  {/* エラー! */}
    </View>
  );
}
 
// ✅ 正しい: <Text> コンポーネントを使う
import { View, Text } from "react-native";
 
export default function App() {
  return (
    <View>
      <Text>Hello World</Text>  {/* OK */}
    </View>
  );
}

解決方法:

  • すべてのテキスト文字列を <Text> でラップする
  • Rork の AI がこのパターンを検出できるよう、生成時に「React Native では Text コンポーネントを必ず使う」と指示する

3. Error: Rendered more hooks than during the previous render

症状: 画面を操作した後、コンソールに Error: Rendered more hooks than during the previous render が表示されます。

原因: React Hooks のルール違反です。以下の 2 つのパターンが典型的です:

  1. Hooks を条件分岐内で呼ぶif (condition) { useState(...) } はダメ
  2. ループ内で Hooks を呼ぶitems.map(() => useEffect(...)) はダメ
// ❌ 間違い: 条件分岐内で useState を呼ぶ
import { useState } from "react";
import { View, Button, Text } from "react-native";
 
export default function Counter() {
  const [isEnabled, setIsEnabled] = useState(false);
 
  // ❌ このif文の中でuseStateを呼ぶと、条件によってHooks数が変わる
  if (isEnabled) {
    const [count, setCount] = useState(0);
  }
 
  return (
    <View>
      <Button title="Enable" onPress={() => setIsEnabled(!isEnabled)} />
    </View>
  );
}
 
// ✅ 正しい: すべての Hooks を関数のトップレベルで呼ぶ
export default function Counter() {
  const [isEnabled, setIsEnabled] = useState(false);
  const [count, setCount] = useState(0);  // トップレベルで呼ぶ
 
  return (
    <View>
      <Button title="Enable" onPress={() => setIsEnabled(!isEnabled)} />
      {isEnabled && <Text>Count: {count}</Text>}
    </View>
  );
}

解決方法:

  • Hooks ルール: Hooks は常にコンポーネントのトップレベルで呼ぶ(条件分岐やループの中では呼ばない)
  • useState / useEffect / useCallback など、すべての React Hooks が対象

4. Module not found / Cannot resolve module

症状: ビルド時またはアプリ起動時に Module not found: Can't resolve 'react-native-gesture-handler' のようなエラーが出る。

原因: インストールされていないパッケージを import したか、バージョンの不整合があります。

// ❌ インストールされていないパッケージをimport
import { GestureHandlerRootView } from "react-native-gesture-handler";  // インストールされていない
 
// ✅ 解決: npm install で追加
// $ npm install react-native-gesture-handler expo-gesture-handler

解決方法:

  • npm install {パッケージ名} でパッケージをインストール
  • 既にインストール済みなら npm install を実行して依存関係を再インストール
  • React Native / Expo のバージョンと互換性を確認(Expo の公式マトリックスを参照)
  • キャッシュをクリア: npx expo start --clear

5. White Screen of Death(白画面)— エラーバウンダリの活用

症状: アプリが起動しても何も表示されず、真っ白な画面が続く。コンソールにはエラーが出ていません。

原因: JavaScript エラーが発生しているが、エラー処理がされておらず、ユーザーに何も表示されていません。

解決方法: エラーバウンダリ(Error Boundary) コンポーネントを実装します。

// components/ErrorBoundary.tsx
import { View, Text, ScrollView } from "react-native";
import { ReactNode } from "react";
 
interface Props {
  children: ReactNode;
}
 
interface State {
  hasError: boolean;
  error: Error | null;
}
 
// エラーバウンダリ: 子コンポーネントで発生したエラーをキャッチして表示
export class ErrorBoundary extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { hasError: false, error: null };
  }
 
  static getDerivedStateFromError(error: Error): State {
    return { hasError: true, error };
  }
 
  componentDidCatch(error: Error, errorInfo: any) {
    console.error("ErrorBoundary caught:", error, errorInfo);
  }
 
  render() {
    if (this.state.hasError) {
      return (
        <ScrollView contentContainerStyle={{ padding: 20, justifyContent: "center" }}>
          <Text style={{ fontSize: 18, fontWeight: "bold", color: "red", marginBottom: 10 }}>
            ⚠️ エラーが発生しました
          </Text>
          <Text style={{ fontSize: 14, color: "#666", marginBottom: 10 }}>
            {this.state.error?.message || "不明なエラー"}
          </Text>
          <Text style={{ fontSize: 12, color: "#999", fontFamily: "monospace" }}>
            {this.state.error?.stack}
          </Text>
        </ScrollView>
      );
    }
 
    return this.props.children;
  }
}

使い方:

// App.tsx
import { ErrorBoundary } from "./components/ErrorBoundary";
 
export default function App() {
  return (
    <ErrorBoundary>
      <YourMainApp />
    </ErrorBoundary>
  );
}

これでアプリが落ちるかわりに、エラー内容がユーザーに表示されます。


Rork のエラーログの読み方

Rork が生成するアプリでエラーが発生した場合、どこを見ればいいか を知ることが解決への第一歩です。

コンソールメッセージの階層

  • 青色メッセージ — デバッグ情報(無視してOK)
  • 黄色メッセージ — 警告(改善推奨)
  • 赤色メッセージ — エラー(修正必須)

エラーメッセージの読み方のコツ

Error: Invariant Violation: Text strings must be rendered within a <Text> component
  at node_modules/react-native/Libraries/Text/Text.js:100
  in MyComponent (at screens/HomeScreen.tsx:25)

この場合:

  • 何が起きた? → Text strings must be rendered within a Text component
  • どこで? → MyComponent
  • そのコンポーネントはどこ? → screens/HomeScreen.tsx の 25 行目

このように、エラーメッセージの上から順に読むことで、問題の箇所を特定できます。


Fix Now(自動デバッグ)機能の活用法

Rork では、エラー検出時に Fix Now 機能を使うことで、AI が自動的にコードを修正してくれます。

  1. エラーが表示されたら、スクリーンショットを撮ってコピー
  2. Rork チャットに貼り付けて「Fix Now」をクリック
  3. AI が修正コードを生成し、アプリに自動適用される

Fix Now が成功したら、修正内容を確認して理解することが大事。その修正パターンを次に生かせます。


Expo Go vs Development Build での違い

Expo Go(プレビューアプリ)と Development Build(カスタムビルド)では、発生するエラーが異なることがあります。

状況Expo GoDevelopment Build
ネイティブモジュール(カメラなど)未対応実行できない実行できる
パフォーマンス遅い(デバッグ情報込み)速い
デバッグ情報詳細少ない
本番環境に近いいいえはい

Expo Go でエラーが出ない = 本番環境でも安全 とは限りません。Development Build でテストしましょう。


Rork Companion アプリでの実機デバッグ

Rork Companion(Mac アプリ)を使うと、実機でのデバッグが格段に楽になります。

  • ライブログ表示 — デバイスのコンソール出力をリアルタイムで表示
  • ホットリロード — コード変更時に自動反映
  • デバイス選択 — 複数デバイスでの同時テスト

Rork Companion の詳しい使い方は「Rork Companion Mac App」を参照してください。


全体を振り返って

Rork で発生する React Native / Expo ランタイムエラーは、一度理由を理解すれば繰り返し学習できます。

  • State の初期化 — 必ず適切な初期値を指定する
  • Text コンポーネント — すべてのテキストをラップする
  • Hooks ルール — 条件分岐やループの外で呼ぶ
  • モジュール互換性 — バージョン確認と npm install を忘れずに
  • エラーバウンダリ — 白画面を防ぐために必須

こうしたパターンをマスターすると、Rork でのアプリ開発がスムーズになります。


参考資料

開発中に参考になる書籍:

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

開発ツール2026-08-31
画面ロックから3分後、expo-audio の環境音は静かに止まっていました
expo-audio の音が画面ロックで止まる原因を、ビルド設定・オーディオセッション・ロック画面連携の三層に分けて切り分けます。Android で約3分後に止まるのは、ドキュメントに書かれた止まり方です。
開発ツール2026-08-24
ダークモードの確認を DevTools に寄せて、実機で見るべき場所が4か所に減りました
Expo SDK 57 の React Native DevTools に入ったライト/ダークのエミュレーションで、端末設定の往復をやめました。差し替わるのは JS が報告する値だけで、実機でしか確認できない場所が残ります。その境界を1画面で切り分ける方法をまとめました。
開発ツール2026-08-23
Android 16 の予測型「戻る」を、8月31日までに直すか後回しにするか
targetSdk 36 では予測型「戻る」が既定で有効になり、onBackPressed が呼ばれなくなります。期限までに必要な作業と、切り離してよい作業を分ける判断と、opt-out を config plugin に置くまでを書きました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →