ReactNativeで簡易コーポレートサイト（アプリ）を作成する #3 -タブバー編-

# 概要
Top・Contactができたので、tabを設置してtabでTopとContactを行き来できるようにします。

# 完成イメージ
<img width="300" alt="000001.jpg" src="https://dl.dropbox.com/s/ht7ttk6q6c384ub/000001.jpg"><img width="300" alt="000010.jpg" src="https://dl.dropbox.com/s/wzmzwbyguf78tat/000010.jpg">

# インストール
https://reactnavigation.org/

react-navigationというライブラリーを使って実装するのでインストールします。
react-navigationとそれに依存するライブラリも一緒にインストールします。


```
expo install react-native-screens react-native-safe-area-context @react-navigation/bottom-tabs @react-navigation/native
```

# タブバー実装
App.jsにタブバーを実装していきます。
一旦、オプションやスタイルを気にせず、最小限のタブを実装するパーツだけを記述してみます。

| キーワード|内容|
|--|--|
|NavigationContainer|遷移の構成や状態など管理するコンポーネント。 画面のコンポーネントは全て NavigationContainerの中に記述する|
|createBottomTabNavigator|タブバーをレンダリングするナビゲーター|

```diff_javascript:App.js
  import React from "react";
+ import { NavigationContainer } from "@react-navigation/native";
+ import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";

  import Top from "./src/screens/Top";
  import Contact from "./src/screens/Contact";

+ const Tab = createBottomTabNavigator();

  export default function App() {
    return (
-     <Contact />
+     <NavigationContainer>
+       <Tab.Navigator>
+         <Tab.Screen
+           name="Top"
+           component={Top}
+         />
+         <Tab.Screen
+           name="Contact"
+           component={Contact}
+         />
+       </Tab.Navigator>
+     </NavigationContainer>
    );
  }
```

```javascript:コピペ用
<NavigationContainer>
  <Tab.Navigator>
    <Tab.Screen
      name="Top"
      component={Top}
    />
    <Tab.Screen
      name="Contact"
      component={Contact}
    />
  </Tab.Navigator>
</NavigationContainer>
```

確認すると、一旦こんな様子です。
<img width="300" alt="000020.jpg" src="https://dl.dropbox.com/s/xop82pxkc7zaexv/000020.jpg">
<img width="300" alt="000030.jpg" src="https://dl.dropbox.com/s/if5qisx5c1icbw2/000030.jpg">


# オプションを追加していく
## アイコン
それぞれのアイコンをつけていきます。

```diff_javascript:App.js
  import React from "react";
  import { NavigationContainer } from "@react-navigation/native";
  import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
+ import { MaterialCommunityIcons } from "@expo/vector-icons";

  import Home from "./src/screens/Home";
  import Contact from "./src/screens/Contact";

  const Tab = createBottomTabNavigator();

  export default function App() {
    return (
      <NavigationContainer>
        <Tab.Navigator>
          <Tab.Screen
            name="Home"
            component={Home}
+           options={{
+             title: "TOP",
+             tabBarIcon: ({ color, size }) => (
+               <MaterialCommunityIcons name="home" color={color} size={size} />
+             ),
+           }}
          />

          <Tab.Screen
            name="Contact"
            component={Contact}
+           options={{
+             title: "お問合せ",
+             tabBarIcon: ({ color, size }) => (
+               <MaterialCommunityIcons name="information" color={color} size={size} />
+             ),
+           }}
          />
        </Tab.Navigator>
      </NavigationContainer>
    );
  }
```
```javascript:コピペ用
<Tab.Screen
  name="Top"
  component={Top}
  options={{
    title: "TOP",
    tabBarIcon: ({ color, size }) => (
      <MaterialCommunityIcons name="home" color={color} size={size} />
    ),
  }}
/>

<Tab.Screen
  name="Contact"
  component={Contact}
  options={{
    title: "お問合せ",
    tabBarIcon: ({ color, size }) => (
      <MaterialCommunityIcons name="information" color={color} size={size} />
    ),
  }}
/>
```

保存して確認します。
<img width="300" alt="000040.jpg" src="https://dl.dropbox.com/s/ii91642rcx3smn0/000040.jpg">



## タブバーとヘッダーのスタイル

|キーワード|内容|
|--|--|
|headerStyle|ヘッダーのスタイルを記述する部分|
|headerTintColor|ヘッダーのタイトルの色|
|headerTitleStyle|ヘッダータイトルのスタイルを記述する部分|
|tabBarStyle|下方のタブのスタイルを記述する部分|
|tabBarInactiveTintColor|タブバーアイコンの色|
|tabBarActiveTintColor|タブバーのアクティブ（表示されている方）の色|

```diff_javascript:App.js
  <NavigationContainer>
    <Tab.Navigator
+     screenOptions={{
+       headerStyle: {
+         backgroundColor: "#666",
+       },
+       headerTintColor: "#fff",
+       headerTitleStyle: {
+         fontWeight: "bold",
+       },
+       tabBarStyle: {
+         backgroundColor: "#666",
+       },
+       tabBarInactiveTintColor: "#ffffff88",
+       tabBarActiveTintColor: "#fff",
+     }}
      >
      <Tab.Screen
        name="Home"
        component={Home}
        options={{
          title: "Welcome",
          tabBarIcon: ({ color, size }) => (
            <MaterialCommunityIcons name="home" color={color} size={size} />
          ),
        }}
      />
      <Tab.Screen
        name="Contact"
        component={Contact}
        options={{
          title: "About",
          tabBarIcon: ({ color, size }) => (
            <MaterialCommunityIcons name="information" color={color} size={size} />
          ),
        }}
      />
    </Tab.Navigator>
  </NavigationContainer>
```

```javascript:コピペ用
<Tab.Navigator
    screenOptions={{
      headerStyle: {
        backgroundColor: "#666",
      },
      headerTintColor: "#fff",
      headerTitleStyle: {
        fontWeight: "bold",
      },
      tabBarStyle: {
        backgroundColor: "#666",
      },
      tabBarInactiveTintColor: "#ffffff88",
      tabBarActiveTintColor: "#fff",
    }}
>
```
これで確認してみます。

## iOS
<img width="300" alt="000050.jpg" src="https://dl.dropbox.com/s/89ydjraeu8b5ry1/000050.jpg">
<img width="300" alt="000060.jpg" src="https://dl.dropbox.com/s/563d1ldizdo21tu/000060.jpg">

## Android
<img width="300" alt="000070.jpg" src="https://dl.dropbox.com/s/0aledm3dnxsz3sy/000070.jpg" > 
<img width="300" alt="000080.jpg" src="https://dl.dropbox.com/s/xlcx4k0f01z2b4n/000080.jpg" > 

これでナビゲーションのタブバーが完成しました。

# 最終的なコード

## App.js

```App.js
import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { MaterialCommunityIcons } from "@expo/vector-icons";

import Top from "./src/screens/Top";
import Contact from "./src/screens/Contact";

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator
        screenOptions={{
          headerStyle: {
            backgroundColor: "#666",
          },
          headerTintColor: "#fff",
          headerTitleStyle: {
            fontWeight: "bold",
          },
          tabBarStyle: {
            backgroundColor: "#666",
          },
          tabBarInactiveTintColor: "#ffffff88",
          tabBarActiveTintColor: "#fff",
        }}
      >
        <Tab.Screen
          name="Top"
          component={Top}
          options={{
            title: "TOP",
            tabBarIcon: ({ color, size }) => (
              <MaterialCommunityIcons name="home" color={color} size={size} />
            ),
          }}
        />

        <Tab.Screen
          name="Contact"
          component={Contact}
          options={{
            title: "お問合せ",
            tabBarIcon: ({ color, size }) => (
              <MaterialCommunityIcons name="information" color={color} size={size} />
            ),
          }}
        />
      </Tab.Navigator>
    </NavigationContainer>
  );
}
```

:::note 
完成したら、iOS/Androidそれぞれでビルドを実行していくことができますが、環境ごとに証明書の設定やビルドの種類の選択など複雑になります。
実行してみたい場合は[Expo公式サイトのドキュメント](https://docs.expo.dev/archive/classic-updates/building-standalone-apps/#3-start-the-build)に詳しい方法が書いてありますので確認してください。
:::

# 関連コンテンツ
* 前：[ReactNativeで簡易コーポレートサイト（アプリ）を作成する #2 -Contact画面編-](https://qiita.com/minimumskills/private/bfecc7a8a6ed57212491)
* [超シンプルなWeb（アプリ）作成を通して各種フロントエンド技術を体験する - 2023 Early -](https://qiita.com/minimumskills/private/9e7efe86e244bb9844b0)