React Navigation v4 BottomTab with a little tweak
Tags: reactnative, reactnavigation
Published: 2022-02-27 08:35:50

Per the title, we are going to do a nested BottomTab with a little tweak. Instead of the usual Icon for the `tabIcon`, we will use `Image`.  

## Adding Navigation

To start, once you have your react native app initialized, please install React Navigation. Please visit the [React Navigation v4 getting started page](https://reactnavigation.org/docs/4.x/getting-started) for the full details on setup. Here is a short walkthrough of the setup.

Install React Navigation v4 and its dependencies as shown below:

```javascript
yarn add react-navigation@4.2.2

yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
```

Once you got your React App and React Navigation ready, let's move on to the next step.

## Minimal example of tab-based navigation

For the navigators, we will need to have 2 tabs. 

```javascript
//Tab1.js
import React from 'react';
import { View, Text, Image, Dimensions } from 'react-native';

import { createAppContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import Ionicons from 'react-native-vector-icons/Ionicons';

import Tab2 from './Tab2'

class Tab1 extends React.Component {
    render() {
      return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <Text>Tab1!</Text>
        </View>
      );
    }
}

const BottomTab = createBottomTabNavigator({
    Tab1: {screen: Tab1},
    Tab2 :{screen: Tab2},
},{
    defaultNavigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, horizontal, tintColor }) => {
        const { routeName } = navigation.state;
        let IconComponent = Ionicons;
        let iconName;
        if (routeName === 'Tab1') {
          iconName = focused ? 'ios-information-circle' : 'ios-information-circle-outline';
        } else if (routeName === 'Tab2') {
            iconName = focused ? 'alarm' : 'alarm-outline';
        }
    
        // You can return any component that you like here!
        return <IconComponent name={iconName} size={25} color={tintColor} />;
      },
    }),
    tabBarOptions: {
      activeTintColor: '#26416d',
      inactiveTintColor: 'gray',
    },
  })

export default createAppContainer(BottomTab);

```

```javascript
//Tab2.js
import React from 'react';
import { View, Text,Button } from 'react-native';

import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';

class Screen1 extends React.Component {
    render() {
      return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <Text>Tab2 Screen1!</Text>
          <Button
            onPress={() => this.props.navigation.navigate('Screen2')}
            title="Go to screen 2"
            color="#f5bebd"
          />
        </View>
      );
    }
}

class Screen2 extends React.Component {
    render() {
      return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <Text>Screen2!</Text>
        </View>
      );
    }
}

const StackNavigator = createStackNavigator({
    Screen1: Screen1,
    Screen2: Screen2,
  });
  
export default createAppContainer(StackNavigator);
```

Here's an example of bottomtab with`Icon`

![Normal bottomtab with icon](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yutq6joo5xexqfpmsi3d.png)


Now, here comes the little tweak. Make sure you have 2 different sets of images. As you can see here, I have pictures for `Profile` and `Settings`. You just need to replace the `tabBarIcon` settings. 

```javascript
defaultNavigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, horizontal, tintColor }) => {
        const { routeName } = navigation.state;
        let IconComponent = Ionicons;
        let iconName;
        if (routeName === 'Tab1') {
          iconName = focused 
          ? require('./profile.png') 
          : require('./profileInactive.png');
        } else if (routeName === 'Tab2') {
            iconName = focused 
            ? require('./settings.png') 
            : require('./settingsInactive.png');
        }
    
        // You can return any component that you like here!
        return <Image source={iconName} style={{height:30, width:30, }}/>;
      },
    })
```

And voila! There you go. 

![Screenshot of a nested react navigation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8a9d83ckpmfas8g7ft7s.png)

As you can see here, when we go to Screen 2, the bottom tab is still there. In order to remove it, we only need to add 

```javascript
tabBarVisible: navigation.state.index === 0
```

under the `defaultNavigationOptions` in the bottomNavigator that we've created. And POOF! 


![comparison between with and without bottomtab](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvzrcc1zkvg57q01w5tm.png)


You can change the image size, or the label size to your liking. You can even change the bottom tab bar to any colour or shape that you want. 

Hope you had fun creating the tab. Bye~