React Navigation でマルチページルーティングを実装

ウェブ開発では、URLバーの変更(例: /home/profile)でページを切り替えるのが一般的です。しかし、スマホアプリにはURLバーが存在しません

ナビゲーションライブラリ(Navigation Library)に依存して画面階層を管理する必要があります。React Nativeエコシステムでは、最も権威があり市場シェアの高いソリューションが React Navigation です。最新のExpo RouterはこれをNext.jsとほぼ同じ「ファイルベースルーティング(File-based Routing)」に進化させました!

1. Expo Routerとは?

以前のRNを書いたことがある方なら、Stack.NavigatorStack.Screen を大量に書く恐怖を覚えているでしょう。

最新版のExpoでは Expo Router が導入されました。これはNext.jsのApp Routerコンセプトを直接借用したものです:フォルダ内に作成したファイルが自動的にページになります!

フォルダ構造は次のようになります:

app/
 ├── _layout.tsx    # グローバルレイアウト設定
 ├── index.tsx      # ホームページ(デフォルトで開く)
 ├── profile.tsx    # プロファイルページ
 └── settings.tsx   # 設定ページ

2. Stack Navigation:スタック型ナビゲーション

スマホアプリで最も一般的なナビゲーション方法が「スタック(Stack)」です。 トランプの山を想像してください。商品をクリックして詳細ページに入るのは、新しいカードを一番上に置くようなものです。左上の < 戻る をクリックすると、一番上のカードを取り除いて前のページに戻ります。

app/_layout.tsx でStackレイアウトを定義します:

import { Stack } from 'expo-router';

export default function RootLayout() {
  return (
    <Stack>
      {/* 異なるページごとにヘッダーをカスタマイズ */}
      <Stack.Screen 
        name="index" 
        options={{ title: 'ホーム', headerShown: false }} 
      />
      <Stack.Screen 
        name="profile" 
        options={{ title: 'プロファイル', presentation: 'modal' }} 
      />
      <Stack.Screen 
        name="settings" 
        options={{ title: 'システム設定' }} 
      />
    </Stack>
  );
}

[!TIP] presentation: 'modal' オプションに注目してください。iOSでは、この設定を追加すると新しいページが「下から上」にスライドして表示されます(デフォルトの右から左ではなく)。これがクラシックなネイティブインタラクション体験です!

3. ページ間の移動(Linkとrouter)

ページができたら、どうやって移動するのでしょうか?Next.jsと非常に似ており、2つの方法があります:

方法1:<Link> コンポーネントを使用(ボタン/テキストに適している)

import { Link } from 'expo-router';
import { View, Text } from 'react-native';

export default function Home() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>ホームへようこそ</Text>
      
      {/* asChildはクリックイベントを内部のTouchableOpacityにバインド */}
      <Link href="/profile" asChild>
        <TouchableOpacity style={{ marginTop: 20, padding: 10, backgroundColor: 'blue' }}>
          <Text style={{ color: 'white' }}>プロファイルへ移動</Text>
        </TouchableOpacity>
      </Link>
    </View>
  );
}

方法2:router APIを使用(関数ロジック内で適している)

import { router } from 'expo-router';

function handleLoginSuccess() {
  // 認証成功後、プログラムで強制移動
  router.push('/dashboard');
  
  // または、ユーザーが戻るボタンでログインページに戻れないようにする場合はreplaceを使用
  // router.replace('/dashboard');
}

4. 実践:IGスタイルのBottom Tabs(底部ナビゲーションバー)を作成

現在、ほぼすべての主流アプリ(Instagram、Line、Spotifyなど)が底部ナビゲーションバーを使用しています。 Expo Routerでこの機能を実装するのは超簡単です!

まず、Tabs専用のフォルダ構造を作成します:

app/
 ├── _layout.tsx         # ルートのStack(ログインページなどTabのない画面用)
 └── (tabs)/             # 括弧はルートグループを示し、URLに表示されない
      ├── _layout.tsx    # Bottom Tabsの見た目を定義
      ├── index.tsx      # ホームTab
      └── explore.tsx    # 探索Tab

app/(tabs)/_layout.tsx を設定します:

import { Tabs } from 'expo-router';
import { Home, Search } from 'lucide-react-native'; // アイコンライブラリをインストール

export default function TabLayout() {
  return (
    <Tabs screenOptions={{ 
      tabBarActiveTintColor: '#3b82f6', // 選択時の色
      headerShown: true // ヘッダーを表示するか
    }}>
      <Tabs.Screen
        name="index"
        options={{
          title: 'ホーム',
          tabBarIcon: ({ color }) => <Home color={color} size={24} />,
        }}
      />
      <Tabs.Screen
        name="explore"
        options={{
          title: '探索',
          tabBarIcon: ({ color }) => <Search color={color} size={24} />,
        }}
      />
    </Tabs>
  );
}

たったこれだけのコードで!iOS/Androidのネイティブデザインガイドラインに完全準拠し、スムースなスライドアニメーションと触覚フィードバックを備えた底部ナビゲーションバーが完成します!

5. パラメータの受け渡し(Route Parameters)

「記事一覧」で記事をクリックして「記事詳細ページ」に移動する場合、記事IDを渡す必要があります。

パラメータを送信:

// 一覧ページで
router.push({ pathname: '/post/[id]', params: { id: 123, title: 'こんにちは' } });

パラメータを受信: ファイル名が app/post/[id].tsx の場合:

import { useLocalSearchParams } from 'expo-router';
import { View, Text } from 'react-native';

export default function PostDetail() {
  // 渡されたパラメータを分解
  const { id, title } = useLocalSearchParams();

  return (
    <View>
      <Text>現在表示中の記事ID: {id}</Text>
      <Text>記事タイトル: {title}</Text>
    </View>
  );
}

ナビゲーションシステムをマスターすれば、アプリに完全な骨格が備わります。次章では、スマホアプリだけが可能な領域に進みます:カメラの呼び出し、GPS位置情報の取得、プッシュ通知の送信!

完全なチュートリアルをロック解除

このチャプターは有料コンテンツです。プロジェクトに参加して、10以上の神レベルのPromptや実際のソースコード例を含む、5000字以上の深い分析をロック解除してください!