基本的なルーティング
前述したファイルベースルーティングを実際に体験してみましょう。
Expo Routerでは、appディレクトリに配置したファイルが自動的に画面として認識され、そのファイル名がURLパスになります。この仕組みを利用すれば、複雑な設定ファイルを作成することなく、直感的に画面構造を設計できます。
例えば、以下のディレクトリ構造を考えてみましょう:
my-router-app/ ├── app/ │ ├── index.js // ホーム画面 (/) │ ├── settings.js // 設定画面 (/settings) │ └── profile/ // プロフィール関連の画面 │ ├── index.js // プロフィール画面 (/profile) │ └── edit.js // プロフィール編集画面 (/profile/edit) └── package.json (他のファイルは省略)
こういったファイル構造を作成すると、それぞれのファイルが自動的に以下のURLパスに対応します:
-
/→app/index.js(アプリを起動した際に最初に表示されるホーム画面) -
/settings→app/settings.js(設定画面) -
/profile→app/profile/index.js(プロフィール画面) -
/profile/edit→app/profile/edit.js(プロフィール編集画面)
各ファイルはReactコンポーネントをデフォルトエクスポートすることで、その画面の内容を定義します。それでは、簡単な例として、ホーム画面から設定画面へ遷移するアプリを作ってみましょう。
まずは、ホーム画面(app/index.js)を作成します(リスト5)。
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Link } from 'expo-router';
// (1)
export default function HomeScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>ホーム画面</Text>
<Text style={styles.subtitle}>
ようこそ、Expo Routerを使ったアプリへ!
</Text>
{/* (2) */}
<Link href="/settings" style={styles.link}>
設定画面へ
</Link>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 10,
},
subtitle: {
fontSize: 16,
textAlign: 'center',
marginBottom: 30,
color: '#666',
},
link: {
marginTop: 15,
paddingVertical: 15,
color: 'blue',
fontSize: 16,
},
});
(1)でデフォルトエクスポートしたコンポーネントが、Expo Routerによって自動的に画面として認識されます。(2)では、後述するLinkコンポーネントを使って、設定画面へのリンクを作成しています。
続いて、設定画面(app/settings.js)を作成します(リスト6)。
import React from 'react';
import { View, Text, StyleSheet, Switch } from 'react-native';
import { Link } from 'expo-router';
export default function SettingsScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>設定画面</Text>
<View style={styles.settingItem}>
<Text style={styles.settingLabel}>ダークモード</Text>
<Switch />
</View>
<View style={styles.settingItem}>
<Text style={styles.settingLabel}>通知</Text>
<Switch />
</View>
<Link href="/" style={styles.link}>ホームに戻る</Link>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 30,
textAlign: 'center',
},
settingItem: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 15,
borderBottomWidth: 1,
borderBottomColor: '#eee',
},
settingLabel: {
fontSize: 16,
},
link: {
marginTop: 30,
paddingVertical: 15,
color: 'blue',
fontSize: 16,
textAlign: 'center',
},
});
これらのコードを実装して実行すると、図2のアプリが動作します。
ホーム画面(index.js)にはタイトルとサブタイトル、そして「設定画面へ」のリンクが表示されます。このリンクをタップすると、設定画面(settings.js)に遷移し、設定項目と「ホームに戻る」リンクが表示されます。「ホームに戻る」をタップすれば、再びホーム画面に戻ります。
この例からわかるように、Expo Routerではファイル作成とコンポーネントの実装だけで、画面構造と遷移フローを簡単に定義できます。ファイル名がURLパスになるという直感的な法則に従うだけで、複雑なルーティング設定が不要になるのです。
また、次回に解説するStack Navigatorなどのナビゲーション支援コンポーネントを組み込むことで、画面遷移時に自動的にスライドアニメーションが適用され、ネイティブアプリらしい体験を提供してくれます。
画面遷移の基本となるLinkコンポーネント
先ほどの例(リスト5、リスト6)でホーム画面と設定画面の相互移動に使用したのが、Expo Routerにおける画面遷移の基本となるLinkコンポーネントです。これはWeb開発における <a> 要素のように機能し、ユーザーがタップすることでhrefプロパティに指定されたルートへ遷移させます。
Linkコンポーネントの最も重要なプロパティはhrefで、ここに遷移先のパスを指定します。パスはappディレクトリの構造に対応した文字列(例: "/settings"や "/profile/edit")で指定するのが基本です。また、次回に解説する動的ルートなどでは、パス名とパラメータをオブジェクト形式で渡すことも可能です(リスト7)。
import { Link } from 'expo-router';
import { View, Text } from 'react-native';
export default function SomeScreen() {
return (
<View>
{/* 文字列でパスを指定 */}
<Link href="/settings">
<Text>設定画面へ</Text>
</Link>
{/* ディレクトリ内のindex.jsへ */}
<Link href="/profile">
<Text>プロフィール画面へ</Text>
</Link>
{/* オブジェクト形式での指定(動的ルート用) */}
<Link href={{ pathname: '/user/[id]', params: { id: '123' } }}>
<Text>ユーザー123のプロフィールへ</Text>
</Link>
</View>
);
}
リスト5やリスト6で見たように、このLinkコンポーネントを画面内に配置することで、ユーザーは他の画面へ簡単に移動できるようになります。
Linkコンポーネントは、子要素としてテキストや他のコンポーネントを受け取ることができます。デフォルトでは内部的にreact-nativeのTextコンポーネントが使われるため、styleプロパティで見た目をカスタマイズすることも可能です。より複雑な見た目のリンクを作成したい場合は、LinkコンポーネントでViewやPressableなどをラップし、asChildプロパティを使用します(これについては次回以降に解説します)。
まとめ
本記事では、Expo Routerの基本的な概念と使い方について解説しました。ファイルベースルーティングを採用することで、appディレクトリの構造がそのままナビゲーションルートとなり、直感的に画面を管理できることをご理解いただけたかと思います。また、Linkコンポーネントを使うことで、宣言的に画面間の遷移を実装できることも学びました。
今回はExpo Routerの導入と最も基本的な機能に焦点を当てましたが、Expo Routerはさらに多くの強力な機能を持っています。
次回は、複数の画面で共通のUI(ヘッダーやタブバーなど)を定義する「レイアウトルート」や、URLの一部をパラメータとして受け取る「動的ルート」など、より複雑なナビゲーションを構築するための機能について詳しく解説します。お楽しみに。
