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-22上級

Rork のバイブコーディングで多画面アプリを破綻させない — 画面分割・状態管理・プロンプトを3段階に分ける設計手順

Rork で4画面を超えるアプリを作ると、画面単体では動くのに遷移の瞬間に状態が消える問題に当たります。原因はプロンプトの構造にあります。3層分離・型付き Context・段階プロンプトで多画面アプリを壊さず育てる手順を、実際に動いた構成とともにまとめました。

Rork515バイブコーディング6アーキテクチャ18マルチ画面状態管理11

Rork で4画面ほどのアプリを組んでいて、画面単体ではきれいに動くのに、画面をまたいだ瞬間に状態が消える。この壁に当たった方は少なくないのではないでしょうか。

私自身、個人開発で長く運営しているユーティリティ系アプリの社内向け管理ツールを Rork で作り直した際、一覧→詳細→設定と遷移するたびに選択中のフィルター条件がリセットされる症状にしばらく付き合うことになりました。

原因はアプリの規模ではありませんでした。プロンプトの構造でした。

多画面アプリで Rork の生成が崩れはじめる典型パターンと、それを防ぐ設計・プロンプトの分割方法を、実際に動いた構成とあわせて共有いたします。

なぜ「多画面になった途端」に壊れるのか

Rork のバイブコーディングは、1画面ずつなら驚くほど正確です。崩れるのはいつも画面の「間」です。

理由ははっきりしています。Rork は修正指示のたびに、該当する画面のコードを丸ごと再生成することがあります。このとき、画面コンポーネントの中に API 呼び出しや状態のロジックを書かせてしまっていると、再生成のたびに他画面との接続部分が上書きされて壊れます。

つまり多画面アプリの守り方は、「再生成されても壊れない場所」にロジックを退避させておくことに尽きます。私は次の3層で指定しています。

  • プレゼンテーション層(screens/): UI と表示ロジックのみ。ここは Rork に何度でも再生成させてよい場所
  • ビジネスロジック層(context/・hooks/): 状態管理とデータ変換。再生成の対象から外すよう明示する場所
  • データ層(services/): Firestore / Supabase / Stripe との通信。一度固めたら触らせない場所

この分離をプロンプトの冒頭で宣言しておくと、Rork は画面を作り直すときも context/ と services/ を温存する傾向がはっきり強まります。体感では、この一文があるかないかで手戻りの回数が目に見えて変わりました。

プロンプトは「構造 → 画面 → 接続」の3段階に分ける

最初に全画面を一気に指定したくなりますが、4画面を超えるアプリでは一括生成は勧めません。私が現在使っている手順は3段階です。

第1段階: 構造だけを先に固定する

このアプリは次の構造で作ってください。
- screens/ には UI のみを置き、API 呼び出しを書かないでください
- 状態は context/ に Context + useReducer で集約してください
- 外部サービスとの通信は services/ にまとめてください
まず空の画面4つとナビゲーションだけを作ってください。

第2段階: 画面を1枚ずつ埋める

eコマースアプリなら、商品一覧(Firestore からカテゴリフィルター付きで取得・カード表示)、商品詳細(説明・レビュー・在庫と「カートに追加」)、カート(数量の増減と小計)、チェックアウト(住所フォームと Stripe 連携)を、この順で1画面ずつ指示します。

第3段階: 接続を明示する

商品一覧で選択したカテゴリフィルターは、詳細画面へ遷移して戻っても
保持してください。この状態は ProductContext に置き、
画面コンポーネント内のローカル state にしないでください。

冒頭で触れたフィルター消失は、まさにこの第3段階を省略したのが原因でした。Rork は「フィルター機能を付けて」とだけ言うと、画面ローカルの useState で実装します。ローカル state は画面がアンマウントされた時点で消えるので、遷移して戻ると初期化されます。どの状態を画面をまたいで生かすのかは、こちらが文章で宣言しない限り伝わりません。

生成後のフォルダ構成は、おおむね次の形に収束します。

src/
├── screens/
│   ├── ProductList.tsx
│   ├── ProductDetail.tsx
│   ├── ShoppingCart.tsx
│   └── Checkout.tsx
├── context/
│   ├── CartContext.tsx
│   └── ProductContext.tsx
├── services/
│   ├── firestoreService.ts
│   └── stripeService.ts
└── navigation/
    └── RootNavigator.tsx

状態管理は「型まで」プロンプトで指定する

複数画面で共有する状態(ログイン情報・カート・フィルター条件)は Context + useReducer に集約しますが、ここで手を抜かずアクションの型まで指定するのが、後で効いてきます。

CartContext は次の型で実装してください。

type CartItem = { productId: string; name: string; price: number; quantity: number };
type CartAction =
  | { type: "ADD_ITEM"; item: CartItem }
  | { type: "REMOVE_ITEM"; productId: string }
  | { type: "SET_QUANTITY"; productId: string; quantity: number }
  | { type: "CLEAR" };

reducer は必ず新しい配列を返し、state.items を直接変更しないでください。

最後の一文は経験からの追加です。以前、数量変更だけ画面に反映されない症状を追いかけたところ、生成された reducer が state.items[i].quantity = n と直接書き換えていて、参照が変わらないため再レンダリングが走っていませんでした。型と合わせて「直接変更しない」まで書いておくと、この種の再現しにくいバグを最初から踏まずに済みます。同じ症状の切り分けはstate が更新されない・再レンダリングされない問題の対処にも詳しくまとめています。

楽観的更新はロールバックとセットで頼む

「カートに追加」のような操作は、体感速度のために楽観的更新にしたいところです。ただし Rork に「楽観的更新にして」とだけ伝えると、成功パスしか実装されないことがあります。失敗時の巻き戻しまでワンセットで指示します。

「カートに追加」は次の順で処理してください。
1. まず UI とローカルの CartContext に即時反映する
2. 並行して Firestore に非同期で保存する
3. 保存に失敗したら CartContext から該当商品を取り除き、
   「追加できませんでした」とトーストで表示する

3 まで書いて初めて、電波の悪い環境でカートと Firestore が食い違う事故を防げます。個人開発では自分ひとりが最初のテスターなので、地下鉄で自分のアプリを触っていて気づいた、という発見が実際に何度かありました。

再生成で壊さないための運用ルール

多画面アプリを Rork で育てるうえで、最終的に一番効いたのは設計そのものより運用ルールでした。私は次の2つを守っています。

修正指示に「触ってよい範囲」を毎回書く。 「詳細画面のレイアウトを直してください。context/ と services/ は変更しないでください」のように、スコープを一文添えます。地味ですが、動いていた接続が巻き添えで壊れる確率が下がります。

接続が絡む変更の前に、動作している状態を書き出しておく。 エクスポートやバージョン履歴で「全画面が繋がって動く地点」を確保してから、次の大きな指示を出します。壊れたら直すのではなく、壊れたら戻れるようにしておく、という順番です。

アーキテクチャのパターン自体をもっと深く比較したい方は、MVVM と Clean Architecture を Rork でどう使い分けるかが次の一歩として繋がるはずです。

まずは今作っているアプリで、画面をまたいで生き残ってほしい状態を紙に3つ書き出し、それを Context に移すプロンプトから試してみてください。多画面の崩れ方が変わるのを実感できると思います。

シェア

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

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

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

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

関連記事

開発ツール2026-07-14
AI再生成に壊されない設計 — Rork の生成コードと手書きロジックを分ける境界の引き方
Rork へ追加指示を出すたびに手書きのロジックが消える。プロンプトで守るのは対症療法です。生成コードと自分の所有コードを層で分け、再生成が届かない境界を設計で引く方法を、Zustand と service 層の実装例つきでお伝えします。
開発ツール2026-07-09
生成のたびに崩れるレイヤ境界を、CIで守る — Rork製Expoアプリの依存ルール機械化
Rorkが生成したExpoアプリを長く運用すると、画面から直接APIクライアントを叩くimportが静かに増えていきます。ESLintのゾーン制約とdependency-cruiserで依存の向きを機械化し、CIで落とすまでの実装を残します。
開発ツール2026-06-22
無印 Rork と Rork Max を1つのバックエンドで支える — 旧バイナリを壊さない API レスポンス契約の設計
無印 Rork(React Native / Expo)と Rork Max(ネイティブ Swift)が同じ Cloudflare Workers バックエンドを叩く構成では、強制アップデートできない旧バイナリを壊さないことが設計の中心になります。レスポンスを封筒型にして加算のみで育て、能力フラグでクライアント差を吸収し、古いバージョンを安全に畳むまでを実装で示します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →