Multiple Navigators in React Navigation 5

Shreyas Nisal
3 min readOct 24, 2020

I previously wrote an article on how to have multiple navigators in react native. However, since react-navigation 5 was released, there have been major changes, and a huge chunk of my previous article may not be as useful anymore. So here’s an article on how to create multiple navigators in react-navigation 5.

Installing Packages

First off, make sure you have all the required packages, as mentioned in the react-navigation documentation. You can install them using this command:

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

Next, since we are going to use the stack, tab and drawer navigators, we need to install these packages too. You can do so using this command

npm install --save @react-navigation/stack @react-navigation/drawer @react-navigation/bottom-tabs

Note: We are using the bottom tab navigator. React Navigation also offers other types of tab navigators, you can try them out too, depending on your requirements.

With this, we’re done with the package installations. Let’s now dive into using these navigators in our project!

Creating Screens

To navigate between screens, we need to first create the screens. You can use your own screens or use the code below to create some demo screens. Our screens will be stored in the /src/routes/ directory, and I’ve omitted the import statements and the styles for brevity.

Home.js

export default class Home extends Component {render() {
return(
<View style={styles.container}>
<TouchableOpacity onPress={() => this.props.navigation.openDrawer()} style={styles.btn}>
<Text>Open Drawer</Text>
</TouchableOpacity>
<Text style={styles.infoText}>Home Screen</Text>
<TouchableOpacity style={styles.btn} onPress={() => this.props.navigation.navigate('StackScreen')}>
<Text>Stack Navigation</Text>
</TouchableOpacity>
</View>
);
}
}

StackScreen.js

export default class StackScreen extends Component {render() {
return(
<View style={styles.container}>
<Text style={styles.infoText}>Stack Screen</Text>
</View>
);
}
}

TabA.js

export default class TabA extends Component {
render() {
return(
<View style={styles.container}>
<TouchableOpacity onPress={() => this.props.navigation.openDrawer()} style={styles.btn}>
<Text>Open Drawer</Text>
</TouchableOpacity>
<Text style={styles.infoText}>Tab-A</Text>
</View>
);
}
}

Navigators

Next, we need to create the navigators. We have 3 navigators, one stack navigator, one drawer navigator, and one tab navigator. Our aim is to navigate between the above 3 screens using these navigators. I created the navigators in different files as mentioned below, and placed them in the /src/navigation/ directory.

StackNavigators.js

const Stack = createStackNavigator()export default class StackNavigator extends Component {
render() {
return(
<Stack.Navigator>
<Stack.Screen name='Home' component={Home} />
<Stack.Screen name='StackScreen' component={StackScreen} />
</Stack.Navigator>
)
}
}

The Stack Navigator is our most straightforward navigator. It has 2 screens, the home screen and the stack screen, both of which we created in the previous section.

TabNavigator.js

const Tab = createBottomTabNavigator()export default class TabNavigator extends Component {
render() {
return(
<Tab.Navigator>
<Tab.Screen name='Home' component={StackNavigator} />
<Tab.Screen name='TabA' component={TabA} />
</Tab.Navigator>
)
}
}

For our Tab Navigator, we have set the home as the stack navigator. This nests our stack navigator inside our tab navigator, and for the “Home” tab, allows us to navigate between any screens in our Stack Navigator.

DrawerNavigator.js

const Drawer = createDrawerNavigator()export default class DrawerNavigator extends Component {
render() {
return(
<Drawer.Navigator drawerContent={(props) => <SideMenu {...props} />}>
<Drawer.Screen name='Home' component={TabNavigator} />
</Drawer.Navigator>
)
}
}

Our Drawer Navigator is the most complex of the 3 navigators we have. Here, we only have the Tab Navigator as the only screen specified. However, what we can additionally do is have a way to navigate to TabA as well. To do that, we have specified a custom drawer content. This option lets us write the component that will be shown inside a drawer, which is going to be a list of screens that we can navigate to using the drawer.

Here is the code for the custom drawer component

SideMenu.js

class SideMenu extends Component {
render() {
return(
<ScrollView>
<TouchableOpacity
style={styles.drawerItem}
onPress={() => {
this.props.navigation.navigate('Home');
this.props.navigation.closeDrawer();
}
}>
<Text style={styles.drawerText}>Home</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.drawerItem}
onPress={() => {
this.props.navigation.navigate('TabA');
this.props.navigation.closeDrawer();
}
}>
<Text style={styles.drawerText}>Tab-A</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.drawerItem}
onPress={() => {
this.props.navigation.navigate('TabB');
this.props.navigation.closeDrawer();
}
}>
<Text style={styles.drawerText}>Tab-B</Text>
</TouchableOpacity>
</ScrollView>
);
}
}

This finishes up our navigators. The last thing we need to do is create the navigation container and place our navigator inside this container. We do this in our App.js file, which after modification will look as given below.

App.js

export default class App extends Component {
render() {
return(
<NavigationContainer>
<DrawerNavigator />
</NavigationContainer>
);
}
}

So that’s it for this article, which corresponds to react-navigation 5. Hope you liked the article; if you did, don’t forget to 👏 for it!

--

--

Shreyas Nisal

Software Engineer at Twilio | Ex Research Assistant at MIT Media Lab, Exertion Games Lab | Ex Intern at Twilio, BitHyve, Mednet Labs