◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/開発ツール
⬡ 開発ツール/2026-07-13上級

WebViewのpostMessageは投げたら終わり — 相関IDで要求と応答を結ぶブリッジを設計する

WebView と React Native の postMessage は片道通信で、送った処理が成功したのか分かりません。相関IDと応答を組み込んだ要求・応答型ブリッジを、動く TypeScript コードで設計します。

WebViewReact Native239Rork585ブリッジTypeScript8

✦ プレミアム記事

送ったはずの保存が、本当に終わったのか分からなかった

Rork で作った個人開発アプリに、既存の Web 版マークダウンエディタを WebView で埋め込んだときのことです。ネイティブ側の「保存」ボタンを押すと、injectedJavaScript でエディタの本文を取り出して自前のバックエンドへ送る。その設計自体は数十分で動きました。

問題は、保存ボタンを押した直後にユーザーが画面を閉じたときでした。本文がまだ取り出せていないのに保存完了のトーストが出る。逆に、通信が遅い端末では二重送信が起きる。原因を追ううちに、根っこは一つだと気づきました。window.ReactNativeWebView.postMessage は投げたら終わりの片道通信で、送った処理が成功したのかを知る仕組みが最初から無いのです。

ここでは、この片道性を埋めるために私が組んだ要求・応答型のブリッジを共有します。相関IDで送信と応答を結びつけ、ネイティブ側からは await bridge.call(...) と書けるようにする設計です。

postMessage が「投げたら終わり」である理由

React Native の WebView 通信は、双方向に見えて実際には独立した二本の片道パイプです。ネイティブから Web へは injectedJavaScript あるいは webviewRef.injectJavaScript() で JavaScript 文字列を流し込む。Web からネイティブへは window.ReactNativeWebView.postMessage(string) を呼び、ネイティブ側の onMessage で受け取る。

この二本には、要求と応答を紐づける仕組みがありません。ネイティブが「本文をくれ」と流し込んだ JavaScript の実行結果が、あとから onMessage に届いたメッセージのどれに対応するのか、フレームワークは教えてくれないのです。メッセージが一種類だけなら気になりません。ところが保存・取得・検証・スクロール位置の問い合わせと種類が増えると、届いた文字列がどの要求への返事なのか判別できず、状態が混線します。

HTTP のリクエストとレスポンスが対応づくのは、TCP コネクションや HTTP/2 のストリームIDが両者を結んでいるからです。postMessage にはそれが無い。ならば、自分で相関IDを持たせればよい。これが設計の出発点でした。

✦

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

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦postMessage の片道性を相関IDで補い、Promise で待てる呼び出しに変える設計
✦タイムアウト5秒・アンマウント・リロードで宙に浮く要求を漏れなく片付ける実装
✦オリジン検証と型ホワイトリストで、埋め込んだ Web を信頼しすぎない防御
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

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

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

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

関連記事

⬡ 開発ツール2026-09-04
EAS の secret は「アプリに入れない」設定ではありません — 接頭辞と可視性を別々に決める
EXPO_PUBLIC_ の接頭辞は成果物に入るかを決め、EAS の可視性は誰が読めるかを決めます。二つを重ねたときに OTA 更新でだけ値が消える筋道と、出荷前に自分の手で確かめる手順をまとめました。
⬡ 開発ツール2026-08-22
一括置換は全ファイル成功しました。壊れたのは、消さなかった行のほうです
生成コードに一括置換をかけると、一致した行ではなく隣の行が壊れます。運用中のプロジェクトで実際に起きた破損と、置換の不変条件を検査する20行のガードスクリプトをまとめました。
⬡ 開発ツール2026-08-14
Expo SDK 57 に上げる前に、prebuild で消えるネイティブ変更を洗い出す
Expo SDK 57 では expo prebuild が既定で ios と android を消してから再生成します。手編集を上げる前に洗い出す方法、config plugin への移し替え、57.0.9 で解消したメモリ回帰までを実務の順序でまとめました。