# 設定畫面Navigation

使用 react-navigation (v1)

[https://v1.reactnavigation.org/docs/tab-based-navigation.html](https://v1.reactnavigation.org/docs/tab-based-navigation.html)

1. 前往 `src/navigatior.js`

### 設置TabBar中每個TabBar的名稱

```
 {
    Home: { screen: Home },
    Counter: { screen: Counter },
    Camera: { screen: Camera },
    PersonalInfo: { screen: PersonalInfo, navigationOptions: { title: '個人資訊' } },
    MerchandiseList: { screen: MerchandiseList, navigationOptions: { title: '我的商品' } },
    NewMerchandise: { screen: NewMerchandise, navigationOptions: { title: '建立商品' } },
    MerchandiseGrid: { screen: MerchandiseGrid, navigationOptions: { title: '商城' } },
    MerchandiseDetail: { screen: MerchandiseDetail, navigationOptions: { title: '商品詳細' } }
  },
```

### 設置TabBar的Icon

對TabNavigator 設置Icon 使用 `react-native-vector-icons/FontAwesome`

與設置選中(active)與沒選中(inactive)的顏色

```
 {
    navigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, tintColor }) => {
        const { routeName } = navigation.state;

        const ICON_MAP = {
          PersonalInfo: 'user',
          MerchandiseList: 'archive',
          NewMerchandise: 'plus',
          MerchandiseGrid: 'th',
          MerchandiseDetail: 'info-circle'
        };
        // You can return any component that you like here! We usually use an
        // icon component from react-native-vector-icons
        return <Icon name={ICON_MAP[routeName] || ''} size={24} color={tintColor} />;
      }
    }),
    tabBarOptions: {
      activeTintColor: 'tomato',
      inactiveTintColor: 'gray'
    },
    tabBarComponent: TabBarBottom,
    tabBarPosition: 'bottom',
    animationEnabled: false,
    swipeEnabled: false
  }
```

### 調整TabBar 的高度與Tab中 每個TabBar的文字大小

在`tabBarOptions` 中 加入style

```
const styles = StyleSheet.create({
  tabBar: {
    height: 90
  },
  tabLabel: {
    fontSize: 16
  }
});

...     
tabBarOptions: {
    activeTintColor: 'tomato',
    inactiveTintColor: 'gray',
    style: styles.tabBar,
    labelStyle: styles.tabLabel
},
```

## 將某些畫面不在TabNavigator 中出現

例如相機這是由某個頁面的動作去開啟的行為，不應該在TabBar中出現，使用StackNavigator 包住原本的AppNavigator，並把那些需要全螢幕的畫面放置在StackNavigator中

```
const RootNavigator = new StackNavigator(
  {
    App: { screen: AppNavigator },
    Home: { screen: Home },
    Counter: { screen: Counter },
    Camera: { screen: Camera }
  },
  {
    headerMode: 'none'
  }
);
```

還有部分畫面是屬於某個頁面開啟，但它還是需要TabBar在下面進行操作，因為那些畫面屬於商城的一部分，譬如說個人頁面->上傳商品->商品管理這樣的操作路徑，這時候我們可以在某個Tab頁面的screen放置`StackNavigator` 來做到此事

```
 {
    PersonalInfo: {
      screen: new StackNavigator({
        PersonalInfo: { screen: PersonalInfo, navigationOptions: { title: '商品清單' } },
        MerchandiseList: { screen: MerchandiseList, navigationOptions: { title: '我的商品' } },
        NewMerchandise: { screen: NewMerchandise, navigationOptions: { title: '建立商品' } }
      }),
      navigationOptions: { title: '個人資訊' }
    },
    MerchandiseGrid: { screen: MerchandiseGrid, navigationOptions: { title: '商城' } },
    MerchandiseDetail: {
      screen: MerchandiseDetail,
      navigationOptions: { title: '商品詳細', tabBarVisible: false }
    }
  },
```

## 新增BadgeIcon

* 可以自由發揮layout 的技巧，以下是參考範例
* 以`numberOfBadges`做為傳入參數，代表有幾則通知
*   以setParams 的方式來傳遞numberOfBadges

    ```
      const styles = StyleSheet.create({
        ....
        badge: {
          position: 'absolute',
          right: -20,
          top: -10,
          borderRadius: 15,
          width: 30,
          height: 30,
          backgroundColor: '#e12',
          color: 'white',
          textAlign: 'center',
          fontSize: 20
        }
      });

      const BadgeIcon = (props) => {
        const { numberOfBadges } = props;
        const show = !!numberOfBadges;
        return (
          <View>
            <Icon {...props} />
            {show && <Text style={styles.badge}> {`${numberOfBadges}`}</Text>}
          </View>
        );
      };
    ```

    ![](https://3741471281-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfNCl0-2Tz7pwP50Mpi%2F-LfNCnnzv40pXJQqOOjK%2F-LfNCp-sgr88NyZbiSnB%2F%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202018-06-06%20%E4%B8%8B%E5%8D%883.42.04.png?generation=1558405666625086\&alt=media)

    **更新其他頁面的通知數量**

    * 透過setParams
      * 但只能更新自己，因為每個頁面都有屬於自己的route params
        * 因為react-navigation 有跟redux store 做結合，將想更新的值打到store 內，用key指定要更新的store name e.g. `TransactionRecord`
        * 在navigationOptions 中來接收
* ```
  const setParamsAction = NavigationActions.setParams({
      params: { numberOfBadges: result },
      key: 'TransactionRecord'
    });
  this.props.navigation.dispatch(setParamsAction);
  ```

```javascript
navigationOptions: ({ navigation }) => ({
    tabBarIcon: ({ tintColor }) => {
      const { routeName } = navigation.state;

      const ICON_MAP = {
        PersonalInfo: 'user',
        MerchandiseList: 'archive',
        NewMerchandise: 'plus',
        MerchandiseGrid: 'th',
        MerchandiseDetail: 'info-circle',
        TransactionRecord: 'list',
        ShoppingCart: 'shopping-cart'
      };
      // You can return any component that you like here! We usually use an
      // icon component from react-native-vector-icons
      const routeParams = navigation.state.params || {};

      return (
        <BadgeIcon
          name={ICON_MAP[routeName] || ''}
          size={42}
          color={tintColor}
          numberOfBadges={routeParams.numberOfBadges}
        />
      );
    }
})
```

### 部分頁面關掉TabBar顯示或是部分頁面打開 StackNavigator's Header

```
headerMode - Specifies how the header should be rendered:

    float - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
    screen - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
```

```
const AppNavigator = new TabNavigator(
  {
    MerchandiseGrid: new StackNavigator(
      {
        MerchandiseGrid: {
          screen: MerchandiseGrid,
          navigationOptions: { title: '商城', header: null } // disable header but open all headers in here
        },
        MerchandiseDetail: {
          screen: MerchandiseDetail,
          navigationOptions: { title: '商品詳細', tabBarVisible: false }
        }
      },
      {
        headerMode: 'screen'
      }
    ),
  }
```

參考資料：

[https://github.com/react-navigation/react-navigation/issues/293#issuecomment-279146748](https://github.com/react-navigation/react-navigation/issues/293#issuecomment-279146748)

[https://github.com/react-navigation/react-navigation/issues/608](https://github.com/react-navigation/react-navigation/issues/608)

Why console.log slow

[https://github.com/evgenyrodionov/redux-logger/issues/32](https://github.com/evgenyrodionov/redux-logger/issues/32)
