A Guide for Building Apps with Nested Stacks

Written by saurabh-kataria | Published 2021/01/02
Tech Story Tags: react-native | react-navigation | react | navigator | mobile-app-development | android-app-development | app-development | mobile-app-developers

TLDR A Guide for Building Apps with Nested Stacks is written by MVPbuddy. The idea is to nest different navigators on top of a stack of screens. By providing an initialRouteName, you can route the navigation flow based on the screen name. You can stack any number of screens in stack-navigator. For example, for all logged-in users, the initialRoute name can be set to ‘Home-Screen’ programmatically. For the users, who haven’t interacted yet, it can be ‘Splash-Screen'via the TL;DR App

If you have just started learning react native & devloping screens, you might have gotten stuck or faced some problems when trying to nest different navigators.
It happened with me as well & I had to spend much time to understand the right solution or approach. Hopefully, this article might help you save some time.
Also, I have created a sample app for this concept, whereby the different navigators are nested (link shared at the last section of this article).

Some Context

Typically, an app starts with a splash screen followed up by signup or login screens. And, finally the home page, where you usually see a drawer menu & some bottom-tab navigators.
In this article, I’d share my approach of nesting these navigators:
@react-navigation/stack
@react-navigation/bottom-tabs
@react-navigation/drawer
Here's the link to the react native component that I had published:
https://github.com/mvpbuddy/react-native-nested-navigators
Folder Structure:
The main source files are located in the views folder. All the navigation routes are defined in Root.js
| root
| App.js
| Views
| Root.js --> Main router file
| SplashScreen.js
| TabScreen1.js
| TabScreen2.js
| TabScreen3.js
| TabScreen4.js
| ContactScreen.js

Let’s get started

Our very initial route would be a splash screen And, we’d use createStackNavigator, which provides a way for the app to transition between screens where each new screen is placed on top of a stack.
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import SplashScreen from './SplashScreen';
....

const Stack = createStackNavigator();
function Root({ navigation }) {
    let initialRoute = 'Splash';  
    return (
        <NavigationContainer>
            <Stack.Navigator initialRouteName={initialRoute}
headerMode="screen">
                <Stack.Screen 
                    name="Splash" 
                    component={SplashScreen} 
                    options={
                        title: '',
                        headerShown: false   
                    }          
                />
                ....
            </Stack.Navigator>
        </NavigationContainer>
  );
}
export default Root;
You can stack any number of screens in stack-navigator. By providing an initialRouteName, you can route the navigation flow based on the screen name.
This is essentially helpful, when implementing auth. For example, for all the logged-in users, the initialRouteName can be set to ‘Home-Screen’ programmatically.
For the users, who haven’t interacted yet, the initialRouteName can be ‘Splash-Screen’
Next, let’s create a drawer component MyDrawer, which would basically be a drawer menu with a couple of other screens.
import { createDrawerNavigator, DrawerContentScrollView, 
DrawerItemList, DrawerItem } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

function DrawerSidebarScreen(props) {
  return (
      <DrawerContentScrollView {...props}>
        <View style={backgroundColor: 'blue', height: 100}></View>
        <DrawerItemList {...props} />
      </DrawerContentScrollView>    
  );
}

function MyDrawer({ navigation }) {
  return (
  <Drawer.Navigator initialRouteName="Home"
drawerContent={props =><DrawerSidebarScreen {...props} />}>
      <Drawer.Screen name="Home" component={HomeTabs} />
      <Drawer.Screen name="Contact Us" component={ContactScreen} />
    </Drawer.Navigator>
  );
}
And, we’d create another stack screen by the name Drawer that would use the above component for rendering.
<Stack.Screen 
    name="Drawer" 
    component={MyDrawer} 
    options={
        title: '',
        headerShown: false          
    }         
/>  
When you are ready to show the drawer menu in the subsequent screens, simply add Drawer navigation route on the page
transition:this.props.navigation.navigate('Drawer');
To open the drawer menu:
import { useNavigation } from '@react-navigation/native';
const navigation = useNavigation();
navigation.openDrawer();
You can simply call the openDrawer function onPress of a button or icon.
Now, let’s create a bottom tab navigator component:
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

function HomeTabs({ navigation }) {
  return (
    <Tab.Navigator
      tabBarOptions={
        activeTintColor: 'blue',
        inactiveTintColor: 'gray',
        title: 'Hello',
        style:{height:40, paddingBottom: 10}
      }
    >
      <Tab.Screen name="Tab-1" component={TabScreen1} />
      <Tab.Screen name="Tab-2" component={TabScreen2} />
      <Tab.Screen name="Tab-3" component={TabScreen3} />
      <Tab.Screen name="Tab-4" component={TabScreen4} />
    </Tab.Navigator>
  );
}
You might have noticed in the drawer component, we have defined the initialRouteName as Home, which corresponds to the nested bottom tab component by the name HomeTabs

Conclusion

Once you understand or implement nested navigation, it seems really simple & handy. Please keep up-to-date with latest version of react-navigation library, as these are updated frequently.
Here’s the github repo. link for the complete code:
https://github.com/mvpbuddy/react-native-nested-navigators

Published by HackerNoon on 2021/01/02