react-native-navigation 2.xによる画面遷移

react-native-navigationを使っているアプリのバージョンをv1.xからv2.xにあげる対応を行う機会があったため、v2での記法を元にした流れを記載します。

#react-native-navigationで使う画面の登録
はじめにreact-native-navigationで表示する画面を登録する必要があります。`registerComponent`を使います。
reduxを用いる場合同一のstoreを使用するためにProviderタグで囲む必要があるため、全てのスクリーンをProviderで囲めるようにreduxWrapperという関数でまとめています。registerComponentしなかったスクリーンは使うことが出来ません。
registerComponentの第一引数はスクリーンの名前を自由に付けることが出来ます。
https://wix.github.io/react-native-navigation/#/docs/Usage?id=the-basics


```navigation.js
import { Provider } from 'react-redux';
import { Navigation } from 'react-native-navigation';

import TopScreen from './TopScreen';
import SecondScreen from './SecondScreen';
import ThirdScreen from './ThirdScreen';

const reduxWrapper = (Screen, store) => () => props => (
  <Provider store={store}>
    <Screen {...props} />
  </Provider>
);

export function registerScreens(store) {
  Navigation.registerComponent(
    'navigation.TopScreen',
    reduxWrapper(TopScreen, store),
  );
  Navigation.registerComponent(
    'navigation.SecondScreen',
    reduxWrapper(SecondScreen, store),
  );
  Navigation.registerComponent(
    'navigation.ThirdScreen',
    reduxWrapper(ThirdScreen, store),
  );
.
.
.

}
```

#スプラッシュスクリーンを表示する
一番最初に呼ぶスクリーンを`setRoot`を使って表示します。
`setRoot`の中のオブジェクトがroot>stack>children,options...と入れ子構造になっています。後述する`push`や`mergeOptions`等によって中の値を入れ替え、スクリーンを遷移したり画面内のボタン等の要素を表示・非表示することが出来ます。最初に開く画面はrootが必要です。
また`component`プロパティの中のnameは先ほど`registerComponent`の第一引数でつけた名前と対応しています。
またoptions内でスタイルや表示時のアニメーションを指定することが出来ます。

```navigation.js
Navigation.setRoot({
    root: {
      stack: {
        children: [{
          component: {
            name: 'navigation.TopScreen',
            passProps: {},
          },
        }],
        options: {
          topBar: {
            color: '#ffffff',
            drawBehind: true,
            visible: false,
            height: 0,
          },
          animationType: 'fade',
        },
      },
    },
  });
```

#モーダルスクリーンを表示する
`showModal`を使用します。その名の通りモーダルスクリーンを表示するメソッドです。先ほどのスプラッシュスクリーンの上に重ねて表示するようなイメージです。


```TopScreen.js
Navigation.showModal({
 stack: {
  children: [{
    component: {
      name: 'navigation.SecondScreen',
      options: {
        topBar: {
         visible: true,
         title: {
          text: 'First',
         },
        },
        animationType: 'slide-up',
     },
   },
 }],
},
```

#画面を移動する
先ほどのshowModalは画面の上に画面を重ねるものでしたが、`push`は重ねるのではなく次のページへ移動するイメージです。
以下はSecondScreen.jsからThirdScreen.jsに移動します。

```SecondScreen.js
Navigation.push(componentId, {
   component: {
     name: 'navigation.ThirdScreen',
        options: {
          topBar: {
            title: {
              text: "Third",
            },
          },
    },
  },
}
```

#optionsの中身だけを変える
`mergeOptions`を使用します。Screenの移動後にスタイルを変化させたい時などに使用します。mergeOptionsを用いることでoptionsのブロックのみ要素を変更することが出来ます。

```ThirdScreen.js
Navigation.mergeOptions(componentId, {
 topBar: {
  topBar: {
    backButton: {
      id: 'closeModal',
      title: "cancel",
    },
   },
 },
});
```

#元の画面に戻る
pushで表示した画面はpopで戻り、showModalで表示された画面はdismissModalで戻ります。

```ThirdScreen.js
// pushされた画面から戻る
Navigation.pop(componentId, {
  animationType: 'slide-down',
});

// showModalで表示された画面から戻る
Navigation.dismissModal(componentId, {
  animationType: 'slide-down',
});
```

#topBarに表示したボタンに関数を設定する
画面の上部のバーをtopBarと呼びます。topBarに設定更新ボタンや画面を戻るボタンを設置していますが、処理をボタンに設定するために `navigationButtonPressed`関数を使用します。
まずScreenの最初の方に以下の文を設置します

```
Navigation.events().bindComponent(this);
```

topBarにおいたボタンを押した時どのような処理を行うかを`navigationButtonPressed`関数に書きます。
topBarブロックに設置したボタンのidの値が{ buttonId }に入ります。
`Navigation.events().bindComponent(this);`を事前に実行しないとボタンを押してもnavigationButtonPressedが呼ばれないようです。

```SecondScreen.js
navigationButtonPressed({ buttonId }) {
  const { componentId } = this.props;
    // idに'closeModal'がセットされているボタンが押された時dismissModalが実行される
    switch (buttonId) {
      case 'closeModal':
         Navigation.dismissModal(componentId, {
           animationType: 'slide-down',
         }
       break;
     default:
       break;
   }
}
```

その他仕様等
react-native-navigationドキュメント
https://wix.github.io/react-native-navigation/#/docs/Usage