RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-03-30中級

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

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

React Native209Expo149ランタイムエラーtroubleshooting25

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/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

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

関連記事

開発ツール2026-07-15
「、」が行頭に落ちた — Rork が組んだ名言カードと日本語の禁則処理
React Native の Text は日本語の行頭禁則を保証しません。実測した違反率、WORD JOINER による事前結合の実装、onTextLayout での自動監査、Rork Max(SwiftUI)との挙動差までまとめました。
開発ツール2026-07-10
React Compiler を Expo に入れて、手書き memo を 41 箇所消しました
Rork が生成した React Native 画面に React Compiler を導入し、再レンダリング回数を Profiler で実測しました。手書き memo/useCallback の削除判断、効かない箇所の見分け方、CI での回帰検知までをまとめています。
開発ツール2026-07-09
Amplitude のファネルが一晩で改善したように見えたとき — イベントのスキーマ崩れを自己監査で炙り出す運用メモ
Rork で作ったアプリの Amplitude ファネルで、課金転換率が8%から19%へ跳ね上がったのに売上が動かない。原因はプロパティ名の崩れによる二重計上でした。イベント契約と実行時バリデータで崩れを計測し、段階的に締め直した運用メモです。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →