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:
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.
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:
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:
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.
{
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
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.
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:
Expo might also ask you for a keystore. You can safely select Generate new keystore and Expo will automatically generate it for you.
Great! Your Expo build should now be in progress. It might take a few minutes to build your APK.
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.
Once your download is complete, click on the downloaded file and your device will attempt to install it.
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.