React Native (Expo)とReact Navigationで画面遷移を実装する
Katz
Contents
はじめに
React Native (Expo)では画面遷移を実装するにはReact NavigationかExpo Routerを利用する方法が一般的らしい。今回はReact Navigationを利用した画面遷移の方法について調べたのでまとめる。
React Navigationとは?
- React NativeにはWebページの遷移のような、新しいページに遷移したら古いページに戻るような、ページ履歴を管理するような仕組みを用意していない。
- このようなWebページの遷移、ページ履歴の管理する機能を提供するのがReact Navigationです。React Nativigationを利用すると複数の画面間での画面遷移を実装できる。
実装方法
実装方法としてStatic configurationとDynamic configurationがあるらしい。
名称 | 詳細 |
---|---|
Static configuration | 必要な定型文、Type Scriptの型、ディープリンクなどを簡素化したもの |
Dynamic configuration | Static configurationと比べると柔軟な設定変更に対応しているが、定型文やディープリンクの実装が必要になる。 |
React Navigationを初めて使う人はStatic configurationの方がおすすめらしいので今回はStatic configurationを利用する。
プロジェクト作成
React NativeのExpoプロジェクトを普通に作成すると、Expo Routerがインストールされてしまうので、以下のコマンドを利用して空のプロジェクトを作成する。
npx create-expo-app Project-Name --template blank-typescript
インストール
React Navigationを利用するにあたり以下のパッケージをインストールする。
名称 | 詳細 |
---|---|
@react-navigation/native | React NavigationのパッケージでReact NativeでReact Navigationを利用する時に使う |
@react-navigation/native-stack | React NavigationのパッケージでReact Nativeで画面スタックを利用する時に使う |
@react-navigation/elements | React Navigationのパッケージで画面遷移で利用するヘッダーなどのコンポーネントが定義されている。また画面遷移で利用するヘルパー関数などが定義されている。 |
@react-native-screens | react-navigation/native-stackが依存しているパッケージ |
@react-native-safe-area-context | React NativeでSafeAreaの取り扱いを楽にするパッケージ |
npm install @react-navigation/native @react-navigation/native-stack @react-navigation/elements
yarn add expo
npx expo install react-native-screens react-native-safe-area-context
画面遷移を実装する
Navigation
- HomeとDetailsの2つの画面を作成するのでscreensに登録する
- Homeは初期表示の画面とするのでinitialRouteNameに登録する
- TypeScriptを利用する場合には型周りで警告が出てしまうので、StaticParamListを利用してRootStackParamListを作成する。
const RootStack = createNativeStackNavigator({
initialRouteName: 'Home',
screens: {
Home: HomeScreen,
Details: DetailsScreen,
},
});
const Navigation = createStaticNavigation(RootStack);
type RootStackParamList = StaticParamList<typeof RootStack>;
HomeScreen
- useNavigationでNavigationを取得して、Navigationを利用して画面遷移する
- navigateを呼び出すと、指定した画面に遷移することができる。
function HomeScreen() {
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<NavigationButton onPress={() => navigation.navigate('Details')} text="Go to Details" />
</View>
);
}
type NavigationButtonProps = {
onPress: () => void;
text: string;
}
function NavigationButton({ onPress, text }: NavigationButtonProps) {
return (
<View style={{ width: '100%', paddingHorizontal: 10 }}>
<Button
onPress={onPress}
style={{ width: '100%', padding: 10, alignItems: 'center' }}
>
{text}
</Button>
</View>
);
}
DetailsScreen
- useNavigationでNavigationを取得して、Navigationを利用して画面遷移する
- pushを呼び出すと、遷移先の画面が既に表示されている場合にでも、画面に遷移することができる。(navigateでは既に表示されている場合は画面遷移できない)
- goBackを呼び出すと、一番上にスタックされている画面を削除して、1つ前に表示されていた画面に戻ることができる。
- popToを呼び出すと、複数のスタックした画面を削除して、指定した画面まで戻ることができる。
- popToTopを呼び出すと、一番下にスタックされている画面以外は削除して、一番したに表示されている画面に戻ることができる。
function DetailsScreen() {
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', gap: 10, width: '100%' }}>
<NavigationButton onPress={() => navigation.push('Details')} text="Go to Details" />
<NavigationButton onPress={() => navigation.goBack()} text="Go back" />
<NavigationButton onPress={() => navigation.popTo('Home')} text="Go to Home" />
<NavigationButton onPress={() => navigation.popToTop()} text="Go back to first screen in stack"/>
</View>
);
}
type NavigationButtonProps = {
onPress: () => void;
text: string;
}
function NavigationButton({ onPress, text }: NavigationButtonProps) {
return (
<View style={{ width: '100%', paddingHorizontal: 10 }}>
<Button
onPress={onPress}
style={{ width: '100%', padding: 10, alignItems: 'center' }}
>
{text}
</Button>
</View>
);
}
動作を確認する
最終的にはこのようなコードが出来上がる。
import * as React from 'react';
import {View, Text, Pressable} from 'react-native';
import {createStaticNavigation, StaticParamList, useNavigation} from '@react-navigation/native';
import { createNativeStackNavigator, NativeStackNavigationProp } from '@react-navigation/native-stack';
import { Button } from '@react-navigation/elements';
const RootStack = createNativeStackNavigator({
initialRouteName: 'Home',
screens: {
Home: HomeScreen,
Details: DetailsScreen,
},
});
const Navigation = createStaticNavigation(RootStack);
type RootStackParamList = StaticParamList<typeof RootStack>;
function HomeScreen() {
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<NavigationButton onPress={() => navigation.navigate('Details')} text="Go to Details" />
</View>
);
}
function DetailsScreen() {
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', gap: 10, width: '100%' }}>
<NavigationButton onPress={() => navigation.push('Details')} text="Go to Details" />
<NavigationButton onPress={() => navigation.goBack()} text="Go back" />
<NavigationButton onPress={() => navigation.popTo('Home')} text="Go to Home" />
<NavigationButton onPress={() => navigation.popToTop()} text="Go back to first screen in stack"/>
</View>
);
}
type NavigationButtonProps = {
onPress: () => void;
text: string;
}
function NavigationButton({ onPress, text }: NavigationButtonProps) {
return (
<View style={{ width: '100%', paddingHorizontal: 10 }}>
<Button
onPress={onPress}
style={{ width: '100%', padding: 10, alignItems: 'center' }}
>
{text}
</Button>
</View>
);
}
export default function App() {
return <Navigation />;
}
上記のコードを実行すると以下のような動作になる。
npx expo start

まとめ
- React Navigationを利用するとReact Native (Expo)プロジェクトでも画面遷移が実装できる。
- React Navigationを利用すると複数画面による画面遷移をnavigate・goBack・popTo・popToTopなどで制御できる。
参考文献
- React Native | Navigation
- https://reactnavigation.org/docs/getting-started
- https://github.com/react-navigation/react-navigation/tree/main/packages/native
- https://github.com/react-navigation/react-navigation/tree/main/packages/native-stack
- https://github.com/software-mansion/react-native-screens
- https://github.com/AppAndFlow/react-native-safe-area-context
ABOUT ME