📱

React Native×Expoでの初アプリ開発の経験をシェアします

2024/12/04に公開

この記事はファンタラクティブ2024年アドベントカレンダー 12月4日の記事です

はじめに

こんにちは、ファンタラクティブ エンジニアの矢野です。

この度、弊社では初めてReact Nativeを使ってネイティブアプリを開発し、もう少しでリリースというところまで来ました!今回は、React Nativeのキャッチアップからアプリリリースに至るまでの過程で取り組んだことや感じたことについてお話ししたいと思います。

初めてReact Nativeを触ったときに驚いたのは、Reactとかなり書き味が似ていることです。Webフロントエンドで培った経験がそのまま活かせる場面が多く、学習コストが低いと感じました。一方で、モバイル固有の知識が必要な部分や、ゼロから学び直さなければならないポイントもいくつかあり、そうしたギャップを埋める過程もとても面白かったです。

また、弊社ではReact Nativeを活用するにあたり、Expoというフレームワークも積極的に活用しました。本記事でもExpoに関連した取り組みについて触れていますので、Expoに興味がある方にも参考にしていただける内容になっているかと思います。

これからReact NativeやExpoを学ぼうと考えている方や、モバイル開発に興味のある方の参考になれば嬉しいです!

キャッチアップするためにやったこと

公式ドキュメントを読み込みまくる

どの技術を学ぶ際にもまず基本となることですが、まずは公式ドキュメントを徹底的に読み込みました。

特に、初めて触れる技術では分からないことだらけなので、最初に全体像を掴むためにざっと目を通し、その後必要な部分を繰り返し読むようにしました。また、React NativeやExpoは進化のスピードが速いため、キャッチアップ初期だけでなく、開発中も頻繁に公式ドキュメントに立ち返りながら進めました。

https://reactnative.dev/
https://docs.expo.dev/

OSSのコードを読み漁る

開発を進める中で、例えば「画面遷移の設計はどうする?」「通知の実装ってどう書けばいい?」といった具体的な正解が分からず、手探りで進めざるを得ない場面が多々ありました。その際に非常に役立ったのが、OSS(オープンソースソフトウェア)のコードです。特に、公式ドキュメントで紹介されているOSSや、React NativeやExpoのコミュニティで評価が高いライブラリのコードを重点的に閲覧しました。

例えば、画面遷移の設計やタブレイアウトの実装については、以下のリポジトリが非常に参考になりました:

  • expo-router-tabs-demo

    タブベースのレイアウトを構築する際の実装例が詳しく解説されていて、Expo Routerを使った具体的な実装方法が学べました。

  • expo-router-layouts-example

    スタックレイアウトやネストされたルーティングの設計例が掲載されていて、画面遷移を構築する際に役立ちました。

また、実際に使うOSSライブラリのコードを深く理解しておくと、いざ自分でカスタマイズしたり、問題が発生した際に原因を特定しやすくなるという利点もありました。公式ドキュメントに載っていないような詳細な挙動も、コードを読めば「なるほど、こういう仕組みで動いているのか」と納得でき、開発への応用力につながったと思います。

https://reactnative.dev/showcase

Webフロントエンドと同じところ

宣言的 UI な書き方

React NativeやExpoを活用した開発で強く感じたのは、宣言的UIの書き方の心地よさです。Reactがその基盤となっているだけあって、UIを「どう描画するか」ではなく、「何を描画するか」を記述するスタイルは、ロジックとビューを整理しながらコードを書く上でとても直感的でした。

React NativeはWeb開発の流れをそのまま活かせる点で強みを感じました。特に、HTMLやCSSの知識をそのまま適用できたり、Web開発者に馴染み深いJavaScriptのエコシステムを活用できたりする点は、React Nativeならではの利便性です。

設計の考え方

React NativeやExpoを使ったモバイル開発では、Webフロントエンドと同じ「宣言的UI」の考え方が採用されており、Webで培った「状態管理」や「コンポーネント設計」の知識をそのまま活かせるのが大きな強みです。

例えば、状態管理ではReactのRecoilを参考に他のフレームワークにも応用できるように、設計の考え方に共通点が多いのが特徴です。また、コンポーネント設計でも、粒度や状態の持たせ方といった基本的な設計思想がWebと変わらないため、学習コストを大幅に削減できます。

こうした親和性により、React Nativeの開発を通じて得た知識やスキルは他の分野にも応用可能で、新しい挑戦を楽しみながらスキルを高められる点が非常に魅力的だと感じています。

Webフロントエンドと違うところ

ビルド周りや CI/CD

ビルドやCI/CDの仕組みは未経験者にとって最大の壁のひとつになると感じました。React NativeやExpoの恩恵で多くの作業が簡略化されていますが、それでもWebアプリのデプロイに比べてAndroidやiOSのアプリビルドと配布は格段に複雑です。

Expoの提供するEAS(Expo Application Services)は、ビルドや配布をスムーズに行える素晴らしいサービスです。特に、iOSやAndroidのネイティブビルドをクラウド上で処理してくれるため、ローカル環境に複雑なセットアップをする必要がなく、初心者でも比較的取り組みやすくなっています。

https://expo.dev/eas

一方で、特にiOSでは証明書やプロビジョニングプロファイルといった独特の仕組みを理解する必要があり、この点が大きなハードルでした。どの証明書がどのアプリで使用されているのか、期限切れのタイミング、再発行時の注意点など、細かい管理が求められます。特に、チームで開発している場合は、これらの証明書をどう共有するかも重要な課題です。間違った設定をしてしまうとビルドが失敗したり、アプリがストアに拒否されたりするため、非常に気を使う部分だと感じました。

モバイルの UI のお作法

Webとは異なるUIの「お作法」に注意が必要です。特に、セーフエリアへの配慮は重要で、iPhoneのノッチやAndroidのパンチホールなど、デバイスごとのUI領域を考慮しないと重要なコンテンツが隠れてしまいます。ExpoやReact Nativeにはセーフエリア用のツールが用意されていますが、デザイン段階から意識し、実装時に確認を重ねることが必要です。

また、モバイルには「ブラウザの戻るボタン」がないため、ナビゲーション設計が鍵となります。特定の画面で戻るボタンを非表示にしたり、履歴をリセットするなど、ユーザーが迷わない工夫が求められます。これらの設計は、UIの配置だけでなく、ユーザー体験全体を大きく左右する重要なポイントだと感じました。

難しかったポイント

iOSとAndroidでの動作の違い

React Nativeでの開発は、基本的に同じコードベースでiOSとAndroidの両方に対応できるのが大きな魅力ですが、それでもやはりOSごとの動作の違いには苦労しました。

例えば、スタイルの微妙な差です。iOSではきれいに揃うレイアウトが、Androidでは微妙にズレてしまうことがあり、特にフォントのレンダリングやボタンのデザインが異なるせいで見た目に統一感を出すのが難しい場面が多々ありました。この対応には、条件分岐を書いたり、カスタムスタイルを適用したりと、予想以上に時間がかかりました。

さらに、ネイティブモジュールの動作の違いも厄介でした。例えば、通知機能を実装した際に、iOSでは期待通りの挙動をするのに対し、Androidでは通知の内容が古いものになったり、通知のクリック時にイベントが発火しなかったりする問題が発生しました。このような問題の解決には、ドキュメントやフォーラムを調べたり、デバッグログを追いかけたりと、かなりの試行錯誤が必要でした。

外部ライブラリの検討

特に難しかったのは、ライブラリ選定時の条件の多さです。「React Nativeで使えること」「TypeScriptで書かれていること」「Expoとの互換性があること」など、要件を細かく設定していくと、使用できるライブラリがどんどん絞られていきます。条件を満たすライブラリをやっと見つけても、最新のExpo SDKやReact Nativeのバージョンと互換性がない場合があり、泣く泣く断念したこともありました。特にバージョン依存の問題は開発を止める要因にもなり、プロジェクト全体に影響が出るため、大きな課題でした。

また、「React Native」で検索をかけた際に、React用のライブラリが頻繁にヒットするのもストレスポイントでした。一見するとReact Nativeでも使えそうに見えるのですが、よく調べるとDOMに依存していたり、ネイティブ環境では動作しないことが多く、期待しては落胆するを繰り返しました。調査段階から「使えないものを排除する」手間が発生するのは、開発効率を落とす要因になっていました。

さらに、ライブラリのドキュメントやサポート状況にも課題がありました。一部のライブラリはメンテナンスが停止していたり、最新のReact Nativeの変更に追いついていなかったりすることも少なくありません。そのため、導入した後で「これが原因で動かないのでは?」と疑念を抱きながら調査を続ける状況になることもあり、精神的な負担も感じました。

良かったポイント

スムーズな開発スピード

Reactをベースにした開発なので、特に戸惑うことなくスムーズに進められました。「書き方が分からなくて手が止まる」ということがほとんどなく、状態管理やコンポーネント設計といったアプリ特有の部分も、WebのReact開発の経験をそのまま活かして対応できました。

もちろん、ネイティブ特有の知識が少し必要になる場面もありますが、「ネイティブは詳しくないけどReactなら任せて!」というタイプの開発者でも十分に参加できるのは大きな魅力だと感じました。

デモ共有で盛り上がった

初めてアプリを作る経験だったこともあり、開発がとても楽しく、夢中で取り組みました。進捗が出るたびに動画を撮ってSlackに共有していたのですが、そのたびにみんなの反応でテンションが上がり、さらにモチベーションが高まりました。

少しずつ形になってヌルヌル動くネイティブアプリを見るのは感動的で、結果的に開発スピードもどんどん加速していきました。

また、細かいデモ動画を頻繁に共有していたおかげで、仕様の認識がずれていた部分も早めに調整でき、無駄な手戻りを減らすことができました。この方法は、Web開発にも十分応用できるスタイルだと思います。

今後

これまで業務で培った経験を備忘録として整理し、公開していこうと考えています。同じような課題に直面する方々の参考になれば嬉しいです。

  • expo-secure-storeで学んだiOSストレージ管理の仕組み

https://zenn.dev/funteractiveinc/articles/9f6d420fe3952e

  • ExpoGoと開発ビルドをどう使っていけば良さそうか
  • OS要件とシミュレーターの活用
  • ビルド手法とバージョニング
  • 内部テストと外部テスト

まとめ

今回の開発を通じて、細かな部分での動作確認を徹底し、チーム内で気付いた課題を早めに共有することの重要性を改めて実感しました。特に、モバイルアプリのように複雑なプラットフォームや多様なデバイス環境を対象とする場合、ちょっとした仕様の違いや認識のズレが、思わぬトラブルを引き起こすことがあります。そうしたリスクを未然に防ぐためには、一つひとつの動作や挙動を細かくチェックし、その結果をチームで迅速に共有する仕組みが欠かせません。

また、課題が明確になることで解決への道筋が立てやすくなり、スムーズなトラブルシューティングが可能になります。このような開発プロセスの中で得た学びは、モバイルに限らず、Webや他の開発領域にも応用できる普遍的なものだと感じています。

次回は、うずらさんの記事になります!

ファンタラクティブテックブログ

Discussion