Expo Router v56:React Navigation からの分離
Expo Router v56 はライブラリの登場以来最大の変更です。Expo Router が依存している React Navigation の一部をフォークし、ストリーミング型のサーバーサイドレンダリング(SSR)を導入し、Android を新しい toolbar API と拡張された Native Tabs により iOS と機能的に近づけました。フォークが今回の目玉の変更であり、すべての Expo Router アプリに影響するため最初に説明します。その後、SSR API、Android のツールバー、Native Tabs の新機能について順に見ていきます。
なぜ React Navigation をフォークしたのか
Expo と React Navigation には長い歴史があります。Brent Vatne(Expo の最も長く在籍する従業員であり VP of Engineering)は、@ericvicenti と @satya164 と共に React Navigation の 1.0 と 2.0 を主導し、React Native の旧 NavigationExperimental API や Expo の ex-navigation などから形作られ、React Native エコシステムの標準的なナビゲーションライブラリへと成長しました。
現在、React Navigation は Satya の元で活発に管理されていますが、Expo Router 自体の開発はファイルベースルーティング、Web、サーバーレンダリングなどに最適化された深い内部制御を必要とするようになりました。Satya と協議のうえ、双方にとって最適な前進方法は、Expo Router が最も直接依存している React Navigation の内部部分をフォークすることだと合意しました。
これは React Navigation というプロジェクトを否定する決定ではなく、それぞれのプロジェクトが利用者にとって最も適した方向へ自由に進化できるようにするための決定です。Expo Router にとってフォークすることで、ファイルベースのルーティングや Web、サーバーサイドレンダリングなど Expo Router 固有のユースケースに合わせた変更を加えやすくなります。上流(React Navigation)へすべてを持ち上げると、React Navigation ユーザーに直接適用されない変更を押し付け、全体の複雑化を招く可能性があります。
実務的な理由としては依存関係のバージョン管理問題もあります。過去のリリースでは複数バージョンの React Navigation がインストールされることがあり、問題の原因になっていました。依存する内部部分をフォークすることで互換性の管理がしやすくなり、Expo Router のリリースが予測可能になります。
最後に、Expo Router はデータローダーや SSR といった Web ベースの機能を強化しています。これらは React Navigation の領域外であり、Expo Router に最適化されたコードベースであれば変更が容易です。
あなたへの影響と移行ツール
Expo Router がもはや React Navigation に直接依存しないため、これまで @react-navigation/* から直接インポートしていたコードは利用できなくなります。破壊的な変更であることは認識しているため、移行を容易にするためのツールを用意しています。
- 既存コードベースのすべての React Navigation インポートを
expo-router/react-navigation に置換する codemod を提供しています。
- 手動で移行する場合の手順は移行ガイドに全て記載しています。
- 移行を段階的かつスムーズにするため、ライブラリによる
@react-navigation/core のインポートは少なくとも1リリース分、自動的に expo-router/react-navigation に置換されます。
問題や不具合を見つけた場合は、ぜひお知らせください。
次の取り組み
React Navigation チームと共同で、両ライブラリを同時にサポートできる共有 API を現在作業中です。もしあなたが Expo Router と React Navigation の両方をサポートすべきライブラリを維持しているなら、ぜひご連絡ください。新しい API への適応で協力したいと考えています。
Suspense のカスタマイズ
_layout 内のルートのために Suspense のフォールバックをカスタマイズするサポートを有効にしました。SuspenseFallback をエクスポートして読み込み画面をカスタマイズできます。
import { ActivityIndicator, View } from 'react-native';
import { Stack } from 'expo-router';
export function SuspenseFallback() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" />
</View>
);
}
export default function Layout() {
return <Stack />;
}
サーバーサイドレンダリング(SSR)
既存の API ルート、ミドルウェア、データローダー、静的レンダリングに加えて、本リリースではストリーミング SSR を導入しました。これにより、データ依存で遅くなる UI よりも先に重要な UI 要素を優先的に表示でき、体感パフォーマンスが向上します。
使用は簡単で、アプリ設定の Expo Router コンフィグオプションに unstable_useServerRendering を true に設定するだけです。
ストリーミング SSR の一環として、ルートの HTML メタデータを生成するための新しい方法 generateMetadata を導入しました。また、型安全なデータローダーを作りやすくするユーティリティとして createStaticLoader と createServerLoader を導入しています。
Android ツールバー
SDK 55 で iOS の toolbar サポートを追加しましたが、本リリースでは Android に同等の機能を追加し、クロスプラットフォームの互換性を向上させました。
iOS と同様に、Android の toolbar は左(left)、右(right)、下(bottom)の 3 つの配置に置けます。
Android toolbar に関する利用可能なオプションは toolbar ドキュメントを確認してください。
Native Tabs
昨シーズン(Router v6)に Native Tabs コンポーネントのサポートを追加しました。現在全プラットフォームでの完全サポートに向けて作業中で、次回リリースで API を安定化させることを目指しています。
Expo Router v56 では Native Tabs にいくつか新しいオプションを追加しました。最も要望の多かった機能の一つがタブの選択を防ぐ方法です。本リリースから disabled プロパティを使って、タブバーにタブを表示しつつユーザーによるタップで切り替えられないようにできます。
利用可能なオプションやプラットフォームサポートの詳細は native tabs のリファレンスページを参照してください。
どこから始めるか(Expo Router v56)
この記事からぜひ持ち帰ってほしい要点は次の 3 つです:
- React Navigation のフォークにより、各 Expo Router アプリでは一度だけインポートの更新が必要になります。codemod と互換レイヤーを提供しており、移行は可能な限り簡単にしています。
- ストリーミング SSR、
generateMetadata、新しいローダーヘルパーが Web 向けの Expo Router 体験を向上させます。
- Android にツールバーサポートと拡張された Native Tabs API が追加され、iOS とほぼ同等になりました。
既存アプリをアップグレードする場合は、まず移行ガイドを確認して codemod を実行してください。新しいプロジェクトを始める場合は、SDK 56 でこれらの機能がデフォルトで含まれます。
私たちは Discord と GitHub にいます。作ったものや不具合についてぜひ教えてください。