React Navigation v5 の基本的な操作

##目的
- 既存の日本語の資料ではV4以前のバージョンが多く、情報が少ない
- 公式ドキュメントを読みながら、最低限動作させるのに必要な設定を把握、メモ
- そのメモを共有する

公式ドキュメント
> https://reactnavigation.org/docs/getting-started/

## 環境
- 本日20200709時点では本コードは動作する
- expo:3.21.13
- npm: 6.13.4

## 環境構築
- 必要なコンポーネントをインストールする

```
npm install @react-navigation/native
expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

npm install @react-navigation/stack
```
### 大まかな仕組み
- NavigatorとScreen二つの要素がある。
- Navigatorの中にScreenを含む構成をとる
- NavigationContainerは、それらのマネジメントを行う。他の全コンポーネントをらぷする必要がある


### 画面遷移に必要な最小限の構成

```
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

一つ目の画面HomeScreenを定義
画面遷移時にnavigation.navigateメソッドを使うときのためのモジュールを関数の引数にとる
function HomeScreen( {navigation} ){
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      ボタンにイベントを設置し、navigation.navigate('画面のキー名')を設置
      <Button
      title="GO TO Datails"
      onPress={() => navigation.navigate('Datails')}
      />

      navigation.navigateとnavigation.push　二つの遷移方法がある
      詳細画面からさらに同じ詳細画面へ遷移した場合、navigationは最初の一回以降はむし
      pushは同じ画面出会ってもスタックが積み上がり続ける
    </View>
  );
}
二つ目の画面DatailScreenを定義
function DetailsScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>

    </View>
  );
}

const Stack = createStackNavigator();



function App() {
  return (
  NavigationContainerで全体をラップし、
  StackNavigatorの下に、画面のコンポーネントを設置
    <NavigationContainer>
      <Stack.Navigator>
      nameに画面のキーを設定し、conponentに画面の関数名を紐付ける
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Datails" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
export default App;

```

## navigationの応用
### パラメータを渡す
- navigateメソッドの第２引数にjsonを渡してパラメータを渡す
- 遷移先関数の第一引数で、渡されたパラメータを受け取る

```
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

function HomeScreen( {navigation} ){
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
       title="GO TO Datails"
       onPress={() => {
          /* 次の画面にパラメータを渡す　navigateの第２引数にオブジェクトを渡す */
          navigation.navigate('Datails', {
            itemId: 86,
            otherParam: 'anything you want here',
          });
        }
      }
      />
    </View>
  );
}

function DetailsScreen({ route, navigation }) {
 /* 受け取ったパラメータは第１引数に入る */
  const { itemId } = route.params;
  const { otherParam } = route.params;
  /* 変数を文字で起こすと以下 */
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Text>itemId: {JSON.stringify(itemId)}</Text>
      <Text>otherParam: {JSON.stringify(otherParam)}</Text>

      <Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
      <Button title="Go back" onPress={() => navigation.goBack()} />
    </View>
  );
}

const Stack = createStackNavigator();



function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Datails" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}


export default App;

```

### タブを実装する
- tabNavigatorを利用する

```
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

TabNavigatorをインポートする
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

function HomeScreen( {navigation} ){
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>

    </View>
  );
}

function DetailsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
    </View>
  );
}

TabNavigatorをインスタンス化する
//const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();



function App() {
  return (
    <NavigationContainer>
    TabNavigatorのツリーを実装する
      <Tab.Navigator>
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen name="Settings" component={DetailsScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}


export default App;

```