Learn

React Native side menu step by step guide with examples

React Native side menu step by step guide with examples

Be it an e-commerce app, a cryptocurrency trading app, or a social media app, all modern apps use side menus to offer a seamless navigation experience to their users. Side menus are intuitive to use and barely take up any visible space on the screen.

Implementing side menus in your React Native app can drastically improve navigation efficiency without cluttering the user interface.

In this guide, we’ll walk you through building a complete side menu for your React Native app and show you how Tricentis Testim Mobile can enhance your app development and testing process.

Create a React Native project using expo

I’m using Expo-CLI to create a React Native project. Expo-CLI enables quick development and building of React Native apps, making it an excellent choice for mobile app developers. If you’re new to Expo, you can read more about it here.

Head over to the directory of your choice and run:

expo init react-native-sidemenu

After that, you’ll choose a template for your project, as shown:

Choosing a starter template for your Expo project

 

Choose a blank template to continue. A new Expo project will be created for you. Then, run the app using the following command:

cd react-native-sidemenu && expo start

Project structure

We’ll create a side menu that renders some menus to navigate to different screens in our app. To get started, create the following files and folders inside the root directory.

Side menu project folder structure

 

The screens directory will contain the different screens that your side menu will navigate to. Accordingly, the components folder will contain a generic <Header/> component that you can display on every screen. Also, this header will have a hamburger icon to toggle our side menu.

For brevity, most of the code pertaining to the side menu will reside inside App.js. Finally, DrawerItems.js will contain information about each menu, such as the title and icon to display.

Let’s get started by filling DrawerItems.js with relevant details of the menus your side menu will render.

Add menu information inside DrawerItems.js

Inside DrawerItems.js, create an array of objects where each object contains some information about a menu to be rendered.

export default [
{
name:'Profile',
iconType:'Material',
iconName:'face-profile'
},
{
name:'Settings',
iconType:'Feather',
iconName:'settings'
},
{
name:'Saved Items',
iconType:'Material',
iconName:'bookmark-check-outline'
},
{
name:'Refer a Friend!',
iconType:'FontAwesome5',
iconName:'user-friends'
}
]

As shown above, each object contains the following properties:

  • name: the name of the screen that the side menu navigates to
  • iconType: the icon library where the icon is taken from
  • icon: the name of the icon to display next to each menu

Note that I’m using the expo-vector-icons library for icons. It comes prefigured with an Expo project. If you’re on a React Native CLI project, you can use react-native-vector-icons instead.

Create navigation screens

The side menu will render a list of menu items defined by DrawerItems.js created previously. Since each menu will navigate to a particular screen, let’s create a simple UI to display the name of the screen. Inside Profile.js, add the following code:

import * as React from 'react';
import { View, Text } from "react-native";

export default function ProfileScreen() {
   return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize:16,fontWeight:'700'}}>Profile Screen</Text>
</View>
   );
 }

The above code will render a simple UI, as shown:

Profile screen

 

You can output a simple <Text>  component to display the name of the screen. Similarly, inside Refer.js, add the following code:

import * as React from 'react';
import { View, Text } from "react-native";

export default function ReferScreen() {
   return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize:16,fontWeight:'700'}}>Refer Screen</Text>
</View>
   );
 }

In a similar fashion, let’s also populate Saved.js and Settings.js files:

import * as React from 'react';
import { View, Text } from "react-native";

export default function SavedScreen() {
   return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize:16,fontWeight:'700'}}>Saved Screen</Text>
</View>
   );
 }

import * as React from 'react';
import { View, Text } from "react-native";

export default function SettingsScreen() {
   return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize:16,fontWeight:'700'}}>Settings Screen</Text>
</View>
   );
 }


Great! Your navigation screens are now complete. Now let’s create and render a side menu containing links to these screens.

Configure a React Native side menu for your navigation screens

I’ll use a popular navigation library, react-navigation/drawer, to create the side menu. Side menus are also commonly referred to as drawer menus. Hence, I might use the terms “drawer menu” and “side menu” interchangeably in the next sections.

Install React-Navigation/drawer

Inside the root directory, run the following command to install react-navigation/drawer:
npm i @react-navigation/drawer
Next, let’s set up a drawer navigator to create a side menu.

Create drawer navigator

Import createDrawerNavigator and NavigationContainer from react-navigation/drawer. Then, create a new Drawer instance using the createDrawerNavigator() hook. Next, nest <Drawer.Navigator> the component inside <NavigationContainer>  component.

import * as React from 'react';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';

const Drawer = createDrawerNavigator();

export default function App() {
 return (
<NavigationContainer>
<Drawer.Navigator
drawerType="front"
initialRouteName="Profile"
drawerContentOptions={{
activeTintColor: '#e91e63',
itemStyle: { marginVertical: 10 },
}}
>
</Drawer.Navigator>
</NavigationContainer>
 );
}

The <Drawer.Navigator>  takes a prop initialRouteName that specifies the route of the first screen rendered by the side menu. Since here initialRouteName is set to Profile, it will render the <ProfileScreen>  component whenever the app loads first.

I have also specified some options inside the drawerContentOptions prop. For instance, the itemStyle property takes a styles object and passes that object to each menu item rendered. You can use it to give any margins, paddings, background color, and so on, to your menus. You can pass more props listed here to give more functionality to your side menu.

Render drawer items inside the side menu

We can use <Drawer.Screen>  to create each individual menu and link it to our navigation screens. Each <Drawer.Screen>  component represents a menu item, and all of them must be nested inside the <Drawer.Navigator> component.

Recall that we created an array of objects to store some information about each menu link. Let’s use it to render a list of menu items using <Drawer.Screen> . The following code simply loops through the DrawerItems array and renders a <Drawer.Screen>  component for each:

import * as React from 'react';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';
import ProfileScreen from './screens/Profile';
import SettingsScreen from './screens/Settings';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { Feather } from '@expo/vector-icons';
import { FontAwesome5 } from '@expo/vector-icons';
import SavedScreen from './screens/Saved';
import ReferScreen from './screens/Refer';
import DrawerItems from './constants/DrawerItems';

const Drawer = createDrawerNavigator();

export default function App() {
 return (


       {
         DrawerItems.map(drawer=>)
       }


 );
}

There are a couple of things you need to specify to the <Drawer.Screen>  component. First, you need a name prop that displays on each menu rendered inside the side menu:

Since we also have an icon and iconType property available for each menu, let’s use that information to render an icon next to each menu’s title:


            drawer.iconType==='Material' ?

           :
           drawer.iconType==='Feather' ?

           :

           }}
/>

Finally, you need to link your navigation screen to each <Drawer.Screen> component. You can use the component prop to map each menu to a navigation screen as shown:


            drawer.iconType==='Material' ?

           :
           drawer.iconType==='Feather' ?

           :

           component={
             drawer.name==='Profile' ? ProfileScreen
               : drawer.name==='Settings' ? SettingsScreen
                 : drawer.name==='Saved Items' ? SavedScreen
                   : ReferScreen
           }
         />

You should now have a working side menu, as shown below:

Side menu

 

Great! Let’s add a header to all your navigation screens with a hamburger icon to toggle the side menu.

Add header to each navigation screen

Head over to components/Header.js and add the following code:

import React from 'react';
import {View,Text, StyleSheet, TouchableOpacity,} from 'react-native';
import { Entypo } from '@expo/vector-icons';
import { useNavigation } from '@react-navigation/native';

export default function Header({screen}){
 const navigation = useNavigation();
  return(

navigation.toggleDrawer()}>



{screen}


  )
}

const headerStyles=StyleSheet.create({
   container:{
       position:'absolute',
       top:30,
       left:0,
       width:'100%',
       backgroundColor:'#fa7da7',
       elevation:5,
       height:50,
       display:'flex',
       flexDirection:'row',
       paddingHorizontal:20,
       alignItems:'center',
       justifyContent:'space-between'
   }
});

The <Header>component described above takes a screen prop as a parameter. This screen prop simply contains the title of the screen where the header will be rendered. Inside the component, we render this title along with an icon to toggle the side menu.

The navigation property provides a method toggleDrawer() to show the Side Menu if it’s hidden and vice versa. Now that the <Header> component is up, let’s use it inside <Drawer.Screen> to render it on all Drawer Screens.


       {
         DrawerItems.map(drawer=>
            drawer.iconType==='Material' ?

           :
           drawer.iconType==='Feather' ?

           :

           ,
               headerShown:true,
               header: ({ scene }) => {
                 const { options } = scene.descriptor;
                 const title =
                   options.headerTitle !== undefined
                     ? options.headerTitle
                     : options.title !== undefined
                     ? options.title
                     : scene.route.name;

                 return (

                 );
               }

           }}
           component={
             drawer.name==='Profile' ? ProfileScreen
               : drawer.name==='Settings' ? SettingsScreen
                 : drawer.name==='Saved Items' ? SavedScreen
                   : ReferScreen
           }
         />)
       }

The 
The header prop takes in a function and returns a JSX component. You can return your own <Header>component inside this function. This function also takes a scene object as props that you can use to get the title of the current screen.

You can pass the title computed inside the function as the screen prop to your <Header> component. Now if you check your app, all your navigation screens will render a header with the screen’s name and a hamburger icon as shown:

Profile screen with header

And that’s it! Your side menu can now be toggled via a hamburger icon from the top. Let’s finally test it on a physical device by building an APK.

Test side menu on a physical device

Let’s see how the Side Menu looks and functions on a physical Android device. We’ll make an Android APK build using Expo and install that APK on a physical device.

Build configurational changes

First, you need some configurational changes inside your app.json file.

{
...
"android": {
"package":"com.sidemenu.sidemenuapp",
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#FFFFFF"
}
...
}

Add the package property inside the android key in your app.json file as shown above.

Create APK build

To create an Android APK, build, run the following command:

expo build:android

Expo-CLI will then ask you to log into your Expo account.

Expo build

 

After you authenticate your Expo account, it will prompt you to enter the type of build. The app-bundle is suited for a production build that you may want to publish to the app stores. Since we only want to create an APK for testing, choose the apk option as shown:

Choosing APK for Expo build

 

Expo might also ask you for a keystore. You can safely select Generate new keystore and Expo will automatically generate it for you.

Expo build generating keystore

 

Great! Your Expo build should now be in progress. It might take a few minutes to build your APK.

Expo build success

Install and test APK build on a physical device

Once your build is complete, go to your Expo account to see the build. You can download the APK to your physical device from there.

Download build APK

 

Once your download is complete, click on the downloaded file and your device will attempt to install it.

Installing APK in physical device

 

Awesome! Let’s test how the side menu functions on our own Android device:

Side menu demo

It looks great! You finally have a complete side menu with drawer navigation for your app! You can slide it from the left to toggle the menu or use the hamburger icon on the header.

Once your side menu is fully implemented, it’s time to ensure it functions flawlessly across various devices. In case you wish to test it against some automated tests, you can explore testim mobile. Tricentis Testim Mobile provides a robust platform for testing your mobile applications on both virtual and physical devices. With low-code test authoring, mobile test automation, and comprehensive test execution, Testim Mobile helps Agile teams deliver high-quality mobile apps efficiently.

Conclusion

In this post, you implemented a complete side menu that you can use in your apps right away. If your app is growing large and you’re adding more navigation screens than ever, you’ll want to have a side menu. You can integrate it with your tab navigators to provide a rich navigation experience to your users.

You can also customize your side menu greatly. For instance, you can control how your side menu appears using the drawerType prop. You can also set the overlay’s color using the overlayColor prop. You can find an exhaustive list of functionalities and features you can add to your side menu through props here .Integrating a side menu into your mobile app not only enhances navigation but also provides users with a seamless experience. By leveraging Tricentis Testim Mobile, you can build, test, and optimize your app’s navigation features, ensuring they perform flawlessly in real-world conditions. Start implementing side menus today and take your mobile app’s usability to the next level.

For more in-depth resources and testing solutions, explore Tricentis Testim Mobile.

This post was written by Siddhant Varma.

Siddhant is a full stack JavaScript developer with expertise in front-end engineering. He’s worked with scaling multiple startups in India and has experience building products in the Ed-Tech and healthcare industries. Siddhant has a passion for teaching and a knack for writing. He’s also taught programming to many graduates, helping them become better future developers.

Author:

Guest Contributors

Date: Aug. 16, 2024