ReactNativeアプリの作り方::画面遷移

このページの目標

  • [ ] StackNavigatorを使いこなせるようになる
  • [ ] StackActionに使って変則的な画面遷移も出来るようになる

画面遷移の実装

ReactNavigation

フルスクラッチでの画面遷移実装は大変なのでReactNavigationを利用します。

セットアップ

yarn add react-navigation
yarn add @types/react-navigation -D
yarn start

提供されているNavigator

ReactNavigationはiOSAndroidでよく使われるいくつかの画面切り替えのためのUIコンポーネントを提供しています。今回は一番シンプルなStackNavigatorについて説明します。

  • StackNavigator
  • SwitchNavigator
  • DrawerNavigator
  • TabNavigator
  • BottomTabNavigator
  • MaterialBottomTabNavigator
  • MaterialTopTabNavigator

余談ですが、上記のNavigatorの動作見たいときはExpoで配信されているのでそちらでチェックすると便利です。 https://expo.io/@react-navigation/NavigationPlayground

StackNavigatorについて

StackNavigatorは基本となるもので、画面切り替えと遷移スタックの管理を提供します。何も設定しなくてもヘッダーなどはそれっぽい見た目に合わせてくれます。

実装サンプル

"Hello world!"を表示するだけのアプリがあると仮定して、これをStackNavigator経由で起動します。

Before

//App.tsx ここがルートコンポーネントとする
export default class App extends React.Component<{}, {}> {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>Hello world!!</Text>
      </View>
    );
  }
}

After

// App.tsx
import { createStackNavigator, createDrawerNavigator, NavigationScreenProp, NavigationRoute } from 'react-navigation';
import HomeScreen from './HomeScreen';

// ルートコンポーネントをStackNavigatorに切り替える
export default createStackNavigator({
  [HomeScreen.routeName]: { screen: HomeScreen }
});

各画面に1:1対応するrouteNameというstatic stringを定義します。

// HomeScreen.tsx
export default class HomeScreen extends React.Component<{}, {}> {
  static routeName = '/HomeScreen';
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>Hello world!!</Text>
      </View>
    );
  }
}

画面遷移

ReactNavigationを経由してマウントされたコンポーネントPropsnavigationが入っています。これを利用して他画面への遷移操作ができます。

基本の画面遷移:navigate

createStackNavigatorに登録したスクリーンであればnavigation.navigate(routeName: "hoge")で遷移することができます。

const navigation = this.props.navigation
const params = {userName: "ReactNative太郎"} // 遷移先の画面に値が渡す
navigation.navigate({ routeName: HomeScreen.routeName, params });

複雑な画面遷移: dispatch+StackAction

例えば アプリを起動->ログイン画面->(ログイン成功)->ホーム画面 という画面遷移があった場合、ホーム画面でエッジスワイプや戻るボタン押された際はアプリは終了するべきだと思われます。しかしnavigateを使ってログイン画面からホーム画面に遷移してしまうと戻ることが出来てしまいます。
このような特殊なケースはStackActionを使って詳細な制御する方法があるので紹介します。下記には画面遷移はするがスタックに積まない場合のStackActionの設定を載せました。

https://reactnavigation.org/docs/en/stack-actions.html

const resetAction = StackActions.reset({
  index: 0,
  actions: [NavigationActions.navigate({ routeName: HomeScreen.routeName })],
});
this.props.navigation.dispatch(resetAction);