まえがき
react-nativeアプリを開発していて、**react-navigation(version3.x)**の基本的な使い方がわかってきたので、このライブラリを利用するにあたり知っておくと助かる情報、使い方をまとめました。react-nativeについての説明はしていないので知らない方は先にreact-nativeを調べて理解してください。抜け等あるかもしれませんので、記載しておいた方がいい内容ありましたら編集リクエスト投げてください。
react-navigationとは
react-navigationは、react-nativeアプリのナビゲーション(ルーティング)と履歴を簡単に管理できるライブラリです。ナビゲーション操作ではよく使われるタブバー、ドロワーを簡単に実装できます。
公式サイト(https://reactnavigation.org/)
ナビゲーションの構造を考える
react-navigationでナビゲーションを作る際、はじめに構造を考えないといけません。構造と言ってもわからないと思いますので、例を紹介しながら説明しようと思います。
はじめの分岐
はじめてアプリを起動する人にはチュートリアルスクリーンを、2回目以降はホームスクリーンを表示させたいとします。そうすると構造は下記になります。
root(スイッチ)
- チュートリアルスクリーン
- ホームスクリーン
スイッチの中に、チュートリアルスクリーンとホームスクリーンが同じ階層に並列に存在しているイメージです。
タブでのスクリーン切替
ホームスクリーンでは、タブバーによってホームスクリーンとプロフィールスクリーンとセッティングスクリーンに切り替えられるようにしたいとします。そうすると構造は下記になります。
root(スイッチ)
- チュートリアルスクリーン
- タブ
- ホームスクリーン
- プロフィールスクリーン
- セッティングスクリーン
タブの中に、ホームスクリーンとプロフィールスクリーンとセッティングスクリーンが同じ階層に並列に存在しているイメージです。
ホームスクリーンとプロフィールスクリーンでのスクリーン遷移
ホームスクリーンでボタンを押すとホーム2スクリーンを表示、プロフィールスクリーンで編集ボタンを押すとプロフィールエディットスクリーンを表示したいとします。そうすると構造は下記になります。
root(スイッチ)
- チュートリアルスクリーン
- タブ
- ホームスタック
- ホームスクリーン
- ホーム2スクリーン
- プロフィールスタック
- プロフィールスクリーン
- プロフィールエディットスクリーン
- セッティングスクリーン
ホームスタックの中に、ホームスクリーンとホーム2スクリーンが同じ階層に並列に存在しているイメージです。
ドロワーでのスクリーン切替
タブ内のスクリーンであれば、どこでもドロワーを開けて、ドロワーからタームオブサービススクリーンを表示したいとします。そうすると構造は下記になります。
root(スイッチ)
- チュートリアルスクリーン
- ドロワー
- タブ
- ホームスタック
- ホームスクリーン
- ホーム2スクリーン
- プロフィールスタック
- プロフィールスクリーン
- プロフィールエディットスクリーン
- セッティングスクリーン
- タームオブサービススクリーン
ドロワーの中に、タブとタームオブサービススクリーンが同じ階層に並列に存在しているイメージです。
まとめ
このように、スイッチとスタックとタブとドロワーを駆使して構造を作って行きます。
また基本的に、同じ階層のナビゲーター、スクリーン同士しか切替はできません。
なのでホームスクリーンからプロフィールスクリーンに切替したい場合、一度ホームスタックからプロフィールスタックに切替し、プロフィールスクリーンを表示することになります。
react-navigatorには、これらのナビゲーターを簡単に作ることができるcreateSwitchNavigator
、createStackNavigator
、createBottomTabNavigator
、createDrawerNavigator
が用意されています。
※上記以外にもcreateMaterialTopTabNavigator
やcreateTabNavigator
等もあります。
準備
**CRNA(create-react-native-app)**でアプリケーションを作成します。
次に、react-navigationをインストールします。
npm install create-react-native-app -g
create-react-native-app reactNavigationSample
cd reactNavigationSample
npm install react-navigation --save
ナビゲーションを実装する
構造が決まったので、必要なスクリーンを作成し、react-navigation
を利用して、スイッチ、スタック、タブ、ドロワーにぶら下げていきましょう。
root(スイッチ)
- チュートリアルスクリーン
- ドロワー
- タブ
- ホームスタック
- ホームスクリーン
- ホーム2スクリーン
- プロフィールスタック
- プロフィールスクリーン
- プロフィールエディットスクリーン
- セッティングスクリーン
- タームオブサービススクリーン
スクリーンの準備
今回必要なスクリーンはチュートリアルスクリーン、ホームスクリーン、ホーム2スクリーン、プロフィールスクリーン、プロフィールエディットスクリーン、セッティングスクリーン、タームオブサービススクリーンです。
まず、「screens」フォルダを作成し、下記のように適当にスクリーンを作成していってください。
※react-nativeの説明は行わないので、スクリプトの説明は省きます。
import React, { Component } from 'react'
import { Platform, StyleSheet, View, Text, Button } from 'react-native'
class HomeScreen extends Component {
render () {
return (
<View>
<Text>Home</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
}
})
export default HomeScreen
スタックの作成
ホームスタックとプロフィールスタックを作ります。
ホームスタック内ではホームスクリーンとホーム2スクリーンの切替が可能になります。
root(スイッチ)
- チュートリアルスクリーン
- ドロワー
- タブ
- ホームスタック // ここ
- ホームスクリーン
- ホーム2スクリーン
- プロフィールスタック // ここ
- プロフィールスクリーン
- プロフィールエディットスクリーン
- セッティングスクリーン
- タームオブサービススクリーン
「navigation」フォルダを作成し、AppNavigator.jsを作成しましょう。
import {
createStackNavigator,
createBottomTabNavigator,
createDrawerNavigator,
createSwitchNavigator
} from 'react-navigation'
import HomeScreen from '../screens/HomeScreen'
import Home2Screen from '../screens/Home2Screen'
import ProfileScreen from '../screens/ProfileScreen'
import ProfileEditScreen from '../screens/ProfileEditScreen'
const HomeStack = createStackNavigator(
{
Home: {
screen: HomeScreen
},
Home2: {
screen: Home2Screen
},
},
{
initialRouteName: "Home",
}
)
const ProfileStack = createStackNavigator(
{
Profile: {
screen: ProfileScreen
},
ProfileEdit: {
screen: ProfileEditScreen
},
},
{
initialRouteName: "Profile",
}
)
createStackNavigator
を使って、スタックを作成します。
ホームスタックの中には、ホームスクリーンとホーム2スクリーンが入るので、Home
をキーに対応するスクリーンをホームスクリーンに、Home2
をキーに対応するスクリーンをホーム2スクリーンに設定しています。
initialRouteName
でスタック内の初期表示スクリーンを指定できます。
ホームスタックでは、初期表示スクリーンはホームスクリーンに設定しました。
※Home
に対応するものはスクリーン以外でも設定でき、スタックにしたりタブにしたりできます。
const HomeStack = createStackNavigator(
{
Home: {
screen: HomeScreen
},
Home2: {
screen: Home2Screen
},
},
{
initialRouteName: "Home",
}
)
スタック内でスクリーンの切替を行えるよう修正します。
ホームスクリーン、ホーム2スクリーン、プロフィールスクリーン、プロフィールエディットスクリーン
を下記のように修正しましょう。
import React, { Component } from 'react'
import { Platform, StyleSheet, View, Text, Button } from 'react-native'
class HomeScreen extends Component {
render () {
return (
<View style={styles.container}>
<Text>Home</Text>
<Button
title="go to Home2"
onPress={() => this.props.navigation.navigate('Home2')}
/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
}
})
export default HomeScreen
this.props.navigation.navigate('スクリーンに対応するキー')
でスクリーンの切替ができます。
<Button
title="go to Home2"
onPress={() => this.props.navigation.navigate('Home2')}
/>
スタックが完成しました。
root(スイッチ)
- チュートリアルスクリーン
- ドロワー
- タブ
- ホームスタック(完成)
- ホームスクリーン(完成)
- ホーム2スクリーン(完成)
- プロフィールスタック(完成)
- プロフィールスクリーン(完成)
- プロフィールエディットスクリーン(完成)
- セッティングスクリーン
- タームオブサービススクリーン
タブの作成
タブを作ります。
タブ内ではホームスタックとプロフィールスタックとセッティングスクリーンの切替が可能になります。
root(スイッチ)
- チュートリアルスクリーン
- ドロワー
- タブ // ここ
- ホームスタック(完成)
- ホームスクリーン(完成)
- ホーム2スクリーン(完成)
- プロフィールスタック(完成)
- プロフィールスクリーン(完成)
- プロフィールエディットスクリーン(完成)
- セッティングスクリーン
- タームオブサービススクリーン
AppNavigator.jsに追記しましょう。
import {
createStackNavigator,
createBottomTabNavigator,
createDrawerNavigator,
createSwitchNavigator
} from 'react-navigation'
import HomeScreen from '../screens/HomeScreen'
import Home2Screen from '../screens/Home2Screen'
import ProfileScreen from '../screens/ProfileScreen'
import ProfileEditScreen from '../screens/ProfileEditScreen'
import SettingScreen from '../screens/SettingScreen'
const HomeStack = createStackNavigator(
{
Home: {
screen: HomeScreen
},
Home2: {
screen: Home2Screen
},
},
{
initialRouteName: "Home",
}
)
const ProfileStack = createStackNavigator(
{
Profile: {
screen: ProfileScreen
},
ProfileEdit: {
screen: ProfileEditScreen
},
},
{
initialRouteName: "Profile",
}
)
const Tab = createBottomTabNavigator(
{
Home: HomeStack,
Profile: ProfileStack,
Setting: {
screen: SettingScreen,
},
}
)
export default Tab
createBottomTabNavigator
を使って、タブを作成します。
タブの中には、ホームスタックとプロフィールスタックとセッティングスクリーンが入るので、Home
をキーにホームスタックを、Profile
をキーにプロフィールスタックを、Setting
をキーにセッティングスクリーンを設定しています。
最後にTab
をexport
しておきます。
const Tab = createBottomTabNavigator(
{
Home: HomeStack,
Profile: ProfileStack,
Setting: {
screen: SettingScreen,
},
}
)
export default Tab
タブが完成しました。
root(スイッチ)
- チュートリアルスクリーン
- ドロワー
- タブ(完成)
- ホームスタック(完成)
- ホームスクリーン(完成)
- ホーム2スクリーン(完成)
- プロフィールスタック(完成)
- プロフィールスクリーン(完成)
- プロフィールエディットスクリーン(完成)
- セッティングスクリーン(完成)
- タームオブサービススクリーン
タブの動きの確認
一度動きの確認をします。
App.jsでタブを表示させるよう修正します。
import React from 'react'
import { StyleSheet, Text, View } from 'react-native'
import { createAppContainer } from 'react-navigation'
import AppNavigator from './navigation/AppNavigator'
const AppContainer = createAppContainer(AppNavigator)
export default class App extends React.Component {
render() {
return <AppContainer />
}
}
createAppContainer
を使って、AppNavigator
をコンテナ化します。
※**react-navigation(version2.x)**では勝手にコンテナ化してくれていたみたいですが、**react-native(verison3.x)**では手動でコンテナ化してあげないと動きません。
const AppContainer = createAppContainer(AppNavigator)
yarn start
でexpoを起動させてみましょう。
ドロワーの作成
ドロワーを作ります。
ドロワー内ではタブとタームオブサービススクリーンの切替が可能になります。
root(スイッチ)
- チュートリアルスクリーン
- ドロワー // ここ
- タブ(完成)
- ホームスタック(完成)
- ホームスクリーン(完成)
- ホーム2スクリーン(完成)
- プロフィールスタック(完成)
- プロフィールスクリーン(完成)
- プロフィールエディットスクリーン(完成)
- セッティングスクリーン(完成)
- タームオブサービススクリーン
AppNavigator.jsに追記しましょう。
import {
createStackNavigator,
createBottomTabNavigator,
createDrawerNavigator,
createSwitchNavigator
} from 'react-navigation'
import HomeScreen from '../screens/HomeScreen'
import Home2Screen from '../screens/Home2Screen'
import ProfileScreen from '../screens/ProfileScreen'
import ProfileEditScreen from '../screens/ProfileEditScreen'
import SettingScreen from '../screens/SettingScreen'
const HomeStack = createStackNavigator(
{
Home: {
screen: HomeScreen
},
Home2: {
screen: Home2Screen
},
},
{
initialRouteName: "Home",
}
)
const ProfileStack = createStackNavigator(
{
Profile: {
screen: ProfileScreen
},
ProfileEdit: {
screen: ProfileEditScreen
},
},
{
initialRouteName: "Profile",
}
)
const Tab = createBottomTabNavigator(
{
Home: HomeStack,
Profile: ProfileStack,
Setting: {
screen: SettingScreen,
},
}
)
const Drawer = createDrawerNavigator({
App: Tab,
TermOfService: TermOfService,
})
export default Drawer
createDrawerNavigator
を使って、ドロワーを作成します。
ドロワーの中には、タブとタームオブサービススクリーンが入るので、App
をキーにタブを、TermOfService
をキーにタームオブサービススクリーンを設定しています。
最後にDrawer
をexport
しておきます。
const Drawer = createDrawerNavigator({
App: Tab,
TermOfService: TermOfServiceScreen,
})
export default Drawer
ドロワーが完成しました。
root(スイッチ)
- チュートリアルスクリーン
- ドロワー(完成)
- タブ(完成)
- ホームスタック(完成)
- ホームスクリーン(完成)
- ホーム2スクリーン(完成)
- プロフィールスタック(完成)
- プロフィールスクリーン(完成)
- プロフィールエディットスクリーン(完成)
- セッティングスクリーン(完成)
- タームオブサービススクリーン(完成)
ドロワーの動きの確認
一度動きの確認をします。
yarn start
でexpoを起動させてみましょう。
スイッチの作成
スイッチを作ります。
スイッチ内ではチュートリアルスクリーンとドロワーの切替が可能になります。
root(スイッチ) // ここ
- チュートリアルスクリーン
- ドロワー(完成)
- タブ(完成)
- ホームスタック(完成)
- ホームスクリーン(完成)
- ホーム2スクリーン(完成)
- プロフィールスタック(完成)
- プロフィールスクリーン(完成)
- プロフィールエディットスクリーン(完成)
- セッティングスクリーン(完成)
- タームオブサービススクリーン(完成)
AppNavigator.jsに追記しましょう。
import {
createStackNavigator,
createBottomTabNavigator,
createDrawerNavigator,
createSwitchNavigator
} from 'react-navigation'
import HomeScreen from '../screens/HomeScreen'
import Home2Screen from '../screens/Home2Screen'
import ProfileScreen from '../screens/ProfileScreen'
import ProfileEditScreen from '../screens/ProfileEditScreen'
import SettingScreen from '../screens/SettingScreen'
import TermOfServiceScreen from '../screens/TermOfServiceScreen'
import TutorialScreen from '../screens/TutorialScreen'
const HomeStack = createStackNavigator(
{
Home: {
screen: HomeScreen
},
Home2: {
screen: Home2Screen
},
},
{
initialRouteName: "Home",
}
)
const ProfileStack = createStackNavigator(
{
Profile: {
screen: ProfileScreen
},
ProfileEdit: {
screen: ProfileEditScreen
},
},
{
initialRouteName: "Profile",
}
)
const Tab = createBottomTabNavigator(
{
Home: HomeStack,
Profile: ProfileStack,
Setting: {
screen: SettingScreen,
},
}
)
const Drawer = createDrawerNavigator({
App: Tab,
TermOfService: TermOfServiceScreen,
})
const AppNavigator = createSwitchNavigator({
Tutorial: {
screen: TutorialScreen,
},
Main: Drawer,
})
export default AppNavigator
createSwitchNavigator
を使って、スイッチを作成します。
スイッチの中には、チュートリアルスクリーンとドロワーが入るので、Tutorial
をキーにチュートリアルスクリーンを、Main
をキーにドロワーを設定しています。
最後にAppNavigator
をexport
しておきます。
const AppNavigator = createSwitchNavigator({
Tutorial: {
screen: TutorialScreen,
},
Main: Drawer,
})
export default AppNavigator
Tutorial
からMain
へで切替を行えるよう修正します。
チュートリアルスクリーンを下記のように修正しましょう。
import React, { Component } from 'react'
import { Platform, StyleSheet, View, Text, Button } from 'react-native'
class TutorialScreen extends Component {
render () {
return (
<View style={styles.container}>
<Text>Tutorial</Text>
<Button
title="go to Main"
onPress={() => this.props.navigation.navigate('Main')}
/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
}
})
export default TutorialScreen
スタックの作成で説明したスクリーンの切替はスクリーン以外のドロワーでも切替できます。
ようは引数にキーを入れれば切替が発生します。
this.props.navigation.navigate('キー')
スイッチが完成しました。
root(スイッチ)(完成)
- チュートリアルスクリーン(完成)
- ドロワー(完成)
- タブ(完成)
- ホームスタック(完成)
- ホームスクリーン(完成)
- ホーム2スクリーン(完成)
- プロフィールスタック(完成)
- プロフィールスクリーン(完成)
- プロフィールエディットスクリーン(完成)
- セッティングスクリーン(完成)
- タームオブサービススクリーン(完成)
スイッチの動きの確認
最終チェックです、動きの確認をします。
yarn start
でexpoを起動させてみましょう。
さいごに
はじめに構造を考えてから、create[ XXX ]Navigator
を使って構築していけばうまく行くはずです。
react-nativeでのアプリ開発では欠かせないライブラリだと思いますので、ぜひreact-navigation
の使い方覚えちゃいましょう。
サンプルコードgithubにあげてます。
https://github.com/kousaku-maron/react-navigation-sample-for-qiita