iOSアプリの査定ツールをNext.jsに移植した社内DX事例|React Native to Webの設計指針
「すでにアプリで動いている機能を、Webにも置けないか?」
「Webで作ったツールを、アプリ化したらもっと使われるのでは?」
徳島の中小企業の経営者の方から、こうしたご相談をいただく機会が増えました。アプリとWebは別物に見えて、実は「同じビジネスロジックを別UIで動かす」ことができれば、開発コストを抑えながら接点を増やせる──これは今、地方企業のDXで現実的に効くアプローチのひとつです。
この記事は、みかもデジタルがグループ内のクルマ買取専門店「エムネット」のために実施した、社内DX事例の共有です。同社のiOSアプリ(React Native製・Expo SDK)で配信していた「かんたん自動査定」を、Next.jsで構築されている公式Webサイト(www.m-net.shop)に移植した、その判断の中身を技術的に整理しておきます。
結論|何を再利用して、何を書き直したか
結論を先に置きます。React NativeアプリをNext.js Webへ移植するときに、私たちが採った方針は次のとおりです。
| レイヤー | 判断 | 理由 |
|---|---|---|
| データ(車種マスタ・倍率テーブル) | そのまま再利用(TypeScript型定義含む) | 計算結果の整合性を保証するため |
| 計算ロジック(concept estimate) | そのまま再利用 | 同一入力で同一出力を保証するため |
| UI(フォーム・モーダル) | 書き直し(React Native → React on Web) | WebはネイティブHTML、SEO・アクセシビリティ要件が異なるため |
| 状態管理 | 書き直し(useState は両方に存在するが構成は別) | UIに密着する層なのでUI書き直しに伴って再構築 |
| 永続化(localStorage / AsyncStorage) | Web版では一旦省略 | Webの匿名閲覧前提では保存ニーズが小さい |
ポイントは、「ビジネスロジックは100%再利用、UIは100%書き直し」と境界をはっきり引いたことです。中途半端にUIだけ流用しようとすると、React NativeとReact on Webの差分(StyleSheet vs Tailwind、TouchableOpacity vs button、Modal vs dialogなど)でかえって工数が増えます。
移植前の状態:iOSアプリの構成
移植元のiOSアプリは、Expo(React Native)で構築されています。今回の対象画面である査定機能は、`src/data/carData.ts` にデータと計算関数があり、`src/screens/EstimateScreen.tsx` にUIロジックがある、シンプルな構成でした。
carData.ts の中身
このファイルには、以下が含まれていました。
- 10メーカー・約80車種の
basePrice(新車時の参考価格) - 4段階の
CONDITIONS(良好〜不動車・事故車)と倍率 - 7段階の
MILEAGE_OPTIONS(〜1万km〜15万km以上)と倍率 calculateEstimate(basePrice, year, conditionMultiplier, mileageMultiplier)関数
計算関数は副作用なし、I/Oなしの純粋関数(pure function)。React Nativeにも、Reactにも、Node.jsにも、同じTypeScriptとして使えます。これが「移植する」のではなく「コピーする」レベルで持ち越せる強さです。
EstimateScreen.tsx の中身
UIは、以下の流れで構成されていました。
- 5つの
SelectorButton(自作コンポーネント)でメーカー・車種・年式・走行距離・状態を選ばせる - 選択UIは
Modal + FlatList(モバイル特有の縦スクロール選択) - 「概算買取額を見る」ボタン → アニメーション付きで結果セクションが表示
- 結果は
Animated.timingでフェードイン
このUIは、モバイルアプリとして最適化されています。Webにそのまま持ち込むのは、Modalの作法、アニメーションライブラリ、タップ領域の取り方──すべてが微妙にずれるため、推奨できません。
移植後の状態:Next.js(App Router)の構成
Web版は、Next.js 16(App Router)の構成に合わせて設計し直しました。
ファイル構成
src/lib/carData.ts(データ・計算関数)── アプリの carData.ts をほぼそのままコピーsrc/components/EstimateForm.tsx(インタラクティブUI、'use client')── ゼロから書き直しsrc/app/(public)/estimate/page.tsx(ページラッパ・メタデータ)── ゼロから書き直し
UIの設計判断
Web版で意識的に「アプリと変えた」設計判断は次のとおりです。
- ネイティブの
<select>を採用:自作モーダルではなく、ブラウザ標準のセレクトを使う。アクセシビリティ・キーボード操作・スクリーンリーダー対応が無料で手に入る - 進捗フィードバック:「あと N項目 選択するとボタンが押せます」というヒントを表示。アプリでは画面が縦に長く、選択中の項目が見えやすいが、Webでは段階を可視化したほうが迷子にならない
- disabled状態の視認性を最大化:未完了は灰色、完了で緑+矢印。これは「ボタンが押せないのに押している」ユーザーを防ぐため
- 結果ブロックを別コンポーネント化せず、同一フォーム下に挿入:Webではスクロール量を増やしすぎないことが大事
- 結果後の二択CTA:「LINEで確認をしてみる」と「出張査定を予約」。アプリでは履歴を保存できるため一段階深い導線を許容するが、Webでは「次の一歩」を即座に提示する
計算結果の同一性を保証する仕組み
アプリとWebで「同じ入力 → 同じ結果」を保証するために、私たちが守ったのは次の3点です。
1. データを単一ソースに置く(理想は外部API化)
今回はTypeScriptのモジュールをコピペしました(コードレベルでミラーリング)。本来は、データ部分をAPIサーバ(あるいはCMS)に置いて、アプリとWebが同じエンドポイントを叩くのが正解です。今回はデータが小さく、更新頻度も低いため、コピペで運用します。
2. 計算関数を純粋関数として保つ
calculateEstimate は、入力(basePrice / year / conditionMultiplier / mileageMultiplier)と現在年(new Date().getFullYear())にだけ依存し、副作用ゼロです。React、React Native、Node.js、ブラウザ、どこでも同じ結果を返します。
3. データ変更時の同期チェック
運用ルールとして、carData.ts を変更する場合はアプリ側とWeb側の両方を同時に更新します。CIにテストを置き、両ファイルのデータ整合性を自動チェックする仕組みを将来導入予定です。
徳島の中小企業がアプリ↔Web移植を検討する際の判断軸
みかもデジタルでは、徳島・四国の中小企業からアプリ・Web開発のご相談を受けます。「片方を作ったが、もう片方も欲しい」というケースで、判断軸を3つに整理しています。
判断軸1:UI差分とロジック差分の比率
純粋なビジネスロジック(料金計算、診断、検索条件マッチングなど)が、UIに対して大きい比率で存在するアプリほど、Web移植のコストが下がります。逆に「アニメーション・タッチ操作・ジェスチャ」がコア体験のアプリは、Web版を作っても別物になります。
判断軸2:オフライン要件と通知要件
「電波が悪い場所でも使える」「プッシュ通知で集客したい」が必須なら、アプリ単体運用が合理的です。Webだけで補完できないユースケースかどうかを、最初に確認します。
判断軸3:データ更新の頻度と権限
データが頻繁に変わる場合は、API化が必須です。今回のように年に1〜2回程度の変更で済むなら、コピペ運用でも実用に耐えます。逆に毎日変わるデータをコピペ運用すると、必ず事故が起きます。
今回の移植にかかったコスト感(参考)
外部の方からよく聞かれるので、ざっくりした規模感を共有しておきます。
- データ・計算関数の移植:約1時間(コピペ+型確認)
- EstimateForm コンポーネントの新規実装:約2〜3時間
- ページラッパとメタデータ:約30分
- テスト・本番デプロイ・キャッシュクリア:約30分
- UX改善(進捗ヒント・disabled視認性):約1時間
- 合計:約半日〜1日(実装担当者1名)
ロジック層が綺麗に分離していたため、Web側はほぼUIに集中できました。アプリを最初から「ロジックとUIを分離」する設計で作っておくと、後の Web展開・横展開コストが大きく下がります。
みかもデジタルの位置付け
今回のように、自グループの実プロダクトでDXを実践し、その学びをそのまま外部のお客様への提案に転化していくのが、みかもデジタルの基本スタイルです。徳島の中小企業の方で、「アプリかWebか迷っている」「両方作りたいが予算が心配」というお悩みがあれば、みかもデジタル公式サイトからお気軽にご相談ください。机上の話ではなく、自分たちが実際に通った道筋でお答えします。
よくあるご質問(FAQ)
Q1. ReactとReact Nativeのコードは、どのくらい共通化できるのですか?
A. 副作用のないTypeScript(データ・計算関数・型定義)は、ほぼ100%共通化できます。UIコンポーネントは、Reactは <div>、React Nativeは <View> という根本的な違いがあるため、共通化は難しい範囲があります。React Native for Webという選択肢もありますが、SEO・アクセシビリティ要件が高いWebでは、Web専用のUIを書き直す方が結果的に綺麗です。
Q2. データを毎日更新する業務でも、コピペ運用で耐えられますか?
A. 耐えられません。1日1回以上更新するデータは、API化(あるいはCMSからの取得)が必須です。今回はデータの更新頻度が低いため、運用ルールでカバーできています。
Q3. アプリを先に作るか、Webを先に作るか、どちらが良いですか?
A. 一概に言えませんが、検証段階ならWeb先行をおすすめします。Web→アプリの移植は、API設計が整っていれば比較的軽量です。アプリ先行で作ると、ロジックがUIに張り付く設計になりがちで、Web展開時に書き直しが増えます。
Q4. このような社内DX事例は、他にもありますか?
A. はい、みかもグループ内では複数の事業で似たような事例があります。M-NETの査定ツールに加えて、SOUP(カーコーティング)の問い合わせ動線、みかもレンタカーの予約フロー、ENEOS三加茂SSの店舗情報まわりなど、それぞれの事業で「複数チャネル間で同じ体験を保つ」設計をしています。
Q5. みかもデジタルへの相談は、どのようなプロセスですか?
A. 初回は無料の相談(オンラインまたは対面)で、現状把握と方向性の整理をします。その後、必要に応じて見積・要件定義・契約の流れになります。徳島県内であれば直接訪問も承ります。
まとめ|「ロジックとUIの分離」という地味な原則が、後から効く
iOSアプリの査定ツールをWebに移植した今回のケースは、技術的には派手なものではありません。しかし「ビジネスロジックを純粋関数として書く」「UIは各プラットフォームに最適化する」という地味な原則を、最初から守っていたことで、移植コストを最小限に抑えられました。
徳島・四国の中小企業の方で、アプリとWebの両方を視野に入れたい場合は、設計段階から相談すると、後の展開が格段に楽になります。私たちみかもデジタルは、自グループのDX実践を踏まえた現場感のある提案で、お手伝いできればと思います。
実物を確認したい方は、エムネットのかんたん自動査定をお試しください。今回の移植成果物が、本番で動いている画面そのものです。
