React Navigation 5でReact Nativeのナビゲーションを扱う方法【新API徹底解説】
React Nativeでナビゲーションを扱うとなると、真っ先に思い浮かぶのが「React Navigation」です。
筆者はこのライブラリの大ファンで、React Nativeでナビゲーションを実装する際には常に第一の選択肢としています。その理由は、APIが優れていて直感的に使えるうえ、カスタマイズ性が非常に高い点にあります。
この記事を書くきっかけとなったのは、バージョン5がベータ版から安定版(stable)へと移行したことです。v5では機能面の変更に加えて、ルートの宣言方法がシンプルかつこれまでとはまったく異なる新しいAPIデザインへと刷新されました。
本記事では、新しいAPIを一通り確認しながら、実際のアプリケーションでの活用方法を見ていきます。
元記事は saidhayani.com で公開されたものです。
インストール方法
React Navigationのインストール方法は、以前のバージョン(4.x以前)から少し変わりました。
// 4.x 以前の場合
yarn add react-navigation
v5のインストールは次のようになります。
// yarn の場合
yarn add @react-navigation/native
// npm の場合
npm install @react-navigation/native
最新バージョンのReact Navigationは、アニメーションや画面遷移の制御のために、多くのサードパーティ製ライブラリ(react-native-gesture-handlerなど)に依存しています。そのため、以下のライブラリも必ず一緒にインストールしてください。
// yarn の場合
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
// npm の場合
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
動的なスクリーン定義
新しいAPIの最大の特徴は、ルートの初期化に「動的さ」が導入されたことです。従来は静的に定義する必要があり、基本的には設定ファイル内でルートを宣言していました。
// @flow
import React from "react";
import { createAppContainer, createSwitchNavigator } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
/** ---------Screens----------- */
import HomeScreen from "../Containers/HomeScreen";
import ProfileScreen from "../Containers/ProfileScreen";
import LoginScreen from "../Containers/LoginScreen";
const StackNavigator = createStackNavigator(
{
Home: {
screen: HomeScreen
},
Login: {
screen: LoginScreen,
headerMode: "none"
},
Profile: {
screen: ProfileScreen
}
},
{
initialRouteName: "Home"
}
);
export default createAppContainer(StackNavigator);
一方、新しいAPIでは動的なコンポーネントが導入され、ナビゲーション構成がより柔軟になりました。ルートの宣言は、次のように書けます。
import React from "react"
import { SafeAreaView, StyleSheet, View, Text, StatusBar } from "react-native"
import { NavigationContainer } from "@react-navigation/native"
import { createStackNavigator } from "@react-navigation/stack"
const App: () => React$Node = () => {
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView style={styles.containerStyle}>
<AppNavigation />
</SafeAreaView>
</>
)
}
const Stack = createStackNavigator()
const AppNavigation = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="home">
<Stack.Screen name="home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
)
}
const HomeScreen = () => {
return (
<View style={styles.containerStyle}>
<Text style={styles.title}>Home Screen</Text>
</View>
)
}

この新しい書き方は動的でシンプルであり、react-routerのAPIにもどこか似ています。
動的なオプション設定
これはコミュニティから長年要望されてきた機能です。筆者も旧来の静的な方式には不満を抱えており、ナビゲーションの挙動を動的に変更するのは本当に困難でした。
従来の方法(4.x以前)
古いバージョンのReact Navigationでは、オプションを静的に定義するしかなく、実行時に動的に変更することはできませんでした。
static navigationOptions = {
title: "Sign In",
header: null,
mode: "modal",
headerMode: "none"
};
新しい方法(バージョン5)
v5では、非常にシンプルな動的な方式が採用されました。propsを使えば、どのスクリーンに対してもオプションを設定できます。
const AppNavigation = ({}) => {
let auth = {
authenticated: true,
user: {
email: "user@mail.com",
username: "John",
},
}
let ProfileScreenTitle = auth.authenticated ? auth.user.username : "Profile"
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={{
title: ProfileScreenTitle,
headerTintColor: "#4aa3ba",
headerStyle: {
backgroundColor: darkModeOn ? "#000" : "#fff",
},
}}
/>
<Stack.Screen name="About" component={AboutScreen} />
</Stack.Navigator>
</NavigationContainer>
)
}

動的オプションを使えば、認証状態に応じてタイトルを変更できます。たとえばユーザーがログイン済みなら、画面タイトルをユーザー名に設定したり、ヘッダーの背景色を切り替えたりすることが可能です。
これは特に、動的テーマを使用している場合や、アプリにダークモードを実装したい場合に非常に便利です。
Hooks(フック)
個人的に最も気に入っているのがこの機能で、開発時間を大幅に節約できます。新しいAPIでは、特定のアクションを実行するためのカスタムフックがいくつか導入されました。
以前のバージョンでは、たとえばアクティブなスクリーンの現在のルート名を取得するために、次のようなヘルパー関数を自作する必要がありました。
export function getCurrentRouteName(): string | null {
const tag = "[getCurrentRouteNameSync] "
const navState = getStore().getState().nav
const currentRoute = getActiveRouteState(navState)
console.log(tag + " currentRoute > ", currentRoute)
return currentRoute && currentRoute.routeName ? currentRoute.routeName : null
}
Hooks APIのおかげで、こうした煩雑な処理は不要になり、わずか1行のコードでNavigation APIにアクセスできるようになりました。
たとえば、useRouteフックを使えば、ルート名を簡単に取得できます。
import { useRoute } from "@react-navigation/native"
const AboutScreen = ({ navigation }) => {
const route = useRoute()
return (
<View
style={{
justifyContent: "space-around",
flex: 1,
alignItems: "center",
}}
>
{/* ここでルート名を表示 */}
<Text style={styles.title}>{route.name}</Text>
</View>
)
}
同様のことはuseNavigationStateフックでも可能です。こちらはナビゲーションの状態そのものへのアクセスを提供します。
const navigationState = useNavigationState(state => state)
let index = navigationState.index
let routes = navigationState.routes.length
console.log(index)
console.log(routes)
React Navigationには、ほかにも便利なフックが用意されています。たとえば:
useFocusEffect:スクリーンがロードされた際にフォーカス中の画面に対して副作用を実行するフックuseLinking:ディープリンク(Deep Linking)を処理するフック
ぜひ一度、公式ドキュメントで確認してみることをおすすめします。
まとめ
新しいReact NavigationのAPIは、明確に「静的から動的へ」という方向へ進化しました。これはReact Nativeにおけるナビゲーションの扱い方を大きく変える素晴らしい方向性です。動的ルートはReact Navigationユーザーからの大きな要望であり、この新しい方式によって、より優れたユーザーナビゲーション体験を構築できるようになるでしょう。
React Nativeに関するその他の記事はこちら
お読みいただきありがとうございました。
- GitHub
- メーリングリストへの参加
プロジェクトでReact Native開発者をお探しですか?ぜひご連絡ください。
-
React Native と Native Base を使用して Android ニュース アプリを作成する方法
私たちは物事が絶えず変化する世界に住んでいます。したがって、何が起こっているかを最新の状態に保ちたい場合は、優れたニュースアプリが必要になります. クールな技術を学び、最新の状態を保つために、このブログ投稿では、React Native を使用して Android 用のニュース アプリケーションを作成します。さまざまなニュース チャンネルから見出しを取得し、カテゴリ別に表示します。 完了すると、アプリは次のようになります。それでは早速見ていきましょう。 Expo のインストール方法 では、万博とは? Expo は、React Native アプリをすばやく簡単に構築してデプロイするの
-
React Nativeで動画を背景に使う方法をわかりやすく解説
この記事では、React Nativeで背景動画(backgroundVideo)を作成する方法を解説します。React Nativeを始めたばかりの方は、まず「React Nativeでモバイルアプリ開発を始めるために知っておくべきこと」といった入門記事を読んでおくと理解がスムーズになります。背景動画はアプリのUIに洗練された印象を与える演出手段です。広告の表示やユーザーへのメッセージ伝達など、さまざまな用途に活用できます。今回はPeletonアプリのホーム画面のようなデザインを目標に、実装方法を見ていきましょう。前提条件実装を始める前に、以下の環境が整っている必要があります。react-n