React Navigation 5 を使って React Native のナビゲーションを処理する方法
React Nativeでナビゲーションを扱うときに真っ先に思い浮かぶライブラリといえば、React Navigationです。
筆者はこのライブラリの大ファンで、React Nativeのナビゲーション処理には常に最初の選択肢として採用しています。その理由の一つは、優れていて使いやすいAPIを備え、カスタマイズ性も非常に高いからです。
この記事を書くにあたったきっかけは、バージョン5がベータ版から安定版へと移行したことです。バージョン5にはいくつかの機能変更が加わり、ルートの宣言方法がシンプルかつ新しい設計のAPIへと生まれ変わりました。
本記事では、新しいAPIの概要と、アプリケーションでの活用方法を見ていきます。
元記事は saidhayani.com で公開されています
インストール
React Navigationのインストール方法は、以前のバージョン(4.x以前)から少し変わりました。
// 4.x以前のバージョン
yarn add react-navigation
React Navigation 5のインストールは次のようになります。
// 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(
{
initialRouteName: "Home"
},
{
Home: {
screen: HomeScreen
},
Login: {
screen: LoginScreen,
headerMode: "none",
},
Profile: {
screen: ProfileScreen
}
}
);
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)
React Navigationには、非常にシンプルな動的な手法が用意されています。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