Edupala

Comprehensive Full Stack Development Tutorial: Learn Ionic, Angular, React, React Native, and Node.js with JavaScript

React Native Drawers: Best Practices and Examples

react native drawer profile

In these tutorials, we will implement React Native drawers in different ways. React Native provides several options for implementing drawer navigation in your app. In this tutorial we will use React Native’s navigation drawer to implement the react native drawer.
A navigation drawer is a panel that slides out from the side of the screen and contains a list of navigation options. Users can tap on a navigation option to open the corresponding screen in the app.

In this example we will learn how to implement react native drawer, implement two examples of its and one example contain a custom drawer where we add user profile photos, user name and signature icon. Let’s get started.

React native drawer configuration

An image below is our first example of a React Native drawer menu. To implement this, we need to install and configure React Native Navigation and React Native Drawer. Due to its ease of use and customization, React Native Drawer is commonly used for creating navigation drawers in React Native apps.

Let install following packages in our application.

npm install @react-navigation/native

If your application is install using expo, then we need to install its dependencies of react-navigation/native package as below.

npx expo install react-native-screens react-native-safe-area-context

To used react native drawer we need to install

npm install @react-navigation/drawer 

If you have a Expo managed project, in your project directory, run:

npx expo install react-native-gesture-handler react-native-reanimated

I got error while using react native drawer, if you have face error regarding missing plugins react-native-reanimated/plugin then you need to add the bold highlighted text on babel.config.js

module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: ['react-native-reanimated/plugin'],
  };
};

Create screen for React native drawer component example

Here is our screenshot of the React Native Drawer. We have added React Native Drawer style to the drawer item background, active and inactive items, and more. We also have icon with each drawer item.

React native drawer example

Once the installation is complete, we need to create the screens to be display on react native drawer, in our example we had create three screen in screens folder having have HomeScreen, ContactScreen and SettingScreen.

In the app.js file let import all screen, required library to implement react native drawer.

import { StyleSheet } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { AntDesign, Ionicons } from "@expo/vector-icons";
import HomeScreen from "./screens/HomeScreen";
import ContactScreen from "./screens/ContactScreen";
import SettingSettings from "./screens/SettingSettings";

const Drawer = createDrawerNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator
        screenOptions={{
          headerStyle: { backgroundColor: "#593EFF" },
          headerTintColor: "white",
          drawerActiveBackgroundColor: "#f0e1ff",
          drawerActiveTintColor: "#3c0a6b",
          drawerInactiveBackgroundColor: "transparent",
          drawerInactiveTintColor: "white",
          drawerStyle: { backgroundColor: "#593EFF" },
        }}
      >
        <Drawer.Screen
          name="Home"
          component={HomeScreen}
          options={{
            title: "Home",
            drawerLabel: "Home Screen",
            drawerIcon: ({ color, size }) => (
              <Ionicons name="person" color={color} size={size} />
            ),
          }}
        />
        <Drawer.Screen
          name="Contact"
          component={ContactScreen}
          options={{
            title: "Contact",
            drawerLabel: "Contact Screen",
            drawerIcon: ({ color, size }) => (
              <AntDesign name="contacts" color={color} size={size} />
            ),
          }}
        />
        <Drawer.Screen
          name="Setting"
          component={SettingSettings}
          options={{
            title: "Settings",
            drawerLabel: "Setting Screen",
            drawerIcon: ({ color, size }) => (
              <Ionicons name="settings" color={color} size={size} />
            ),
          }}
        />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

In this example, we imported the NavigationContainer component from the @react-navigation/native library and wrapped our DrawerNavigator inside it. This is required to set up the navigation context and render the navigation components.

React native drawer style

To style the drawer in React Native, there are several options available. Here in this example we don’t used custom drawer component, in next example we will implement it. We can specify the background color, position of the drawer, its width, and other properties. You can also customize the style of the drawer using CSS-like properties such as backgroundColor, padding, and borderRadius. In above code we already add the styling of the drawer.

To apply style like color style to to all Drawer screens, like the navigation stack we can add a single common option at the parent component that is Drawer.Navigation screensOptions as below

    <NavigationContainer>
      <Drawer.Navigator
        screenOptions={{
          headerStyle: { backgroundColor: "blue" },
          headerTintColor: "white",
          drawerActiveBackgroundColor: "#343433",
          drawerActiveTintColor: "white",
          drawerStyle: { backgroundColor: "grey" },
        }}
      >
        <Drawer.Screen
          name="Home"
          component={HomeScreen}
          options={{
            drawerLabel: "Home",
            drawerIcon: ({ color, size }) => (
              <Ionicons name="home" color={color} size={size} />
            ),
          }}

Adding style while focused on drawer screen item.

<Drawer.Screen
name="Contact"
component={ContactScreen}
options={{
title: "Contact",
drawerLabel: "Contact Screen",
drawerIcon: ({ color, size, focused }) => (
<AntDesign
name="contacts"
color={focused ? "#CB242E" : color}
size={focused ? 30 : size}
/>
),
}}
/>

Accessing route and navigation props in register screen component

Inside the register screen component on Drawer.Navigator, we will have route and navigation as props. The navigation props in Drawer support an extra method called toggleDrawer to toggle the drawer on or off.

const HomeScreen = ({ route, navigation }) => {
  const openDrawerHandler = () => {
       navigation.toggleDrawer();
  };

  return (
    <View>
       ....
      <Button title="Open Drawer" onPress={openDrawerHandler} />
    </View>
  );
};

React native custom Drawer

In our second example we will implement React native custom drawer. One of its key features is the ability to create custom drawers, which can be used to provide navigation and other functionality to users. In our custom drawer let add profile image, logout button and more, here is our screenshot of it.

react native drawer profile

Step 1: For custom directive, we need to add following code in App.js for react drawer navigation item list. We also need to add all the screen that are used inside the navigation drawer. We need to import our custom drawer component and pass it inside the drawerContent in DrawerNavigation with props in CustomDrawer component.

import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from "@react-navigation/native";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { AntDesign, Ionicons } from "@expo/vector-icons";
import HomeScreen from "./screens/HomeScreen";
import ContactScreen from "./screens/ContactScreen";
import SettingScreen from "./screens/SettingScreen";
import CustomDrawer from "./components/CustomDrawer";

const Drawer = createDrawerNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator
      drawerContent={props => <CustomDrawer { ...props } />}
        screenOptions={{
          headerStyle: { backgroundColor: "#593EFF" },
          headerTintColor: "white",
          drawerActiveBackgroundColor: "#f0e1ff",
          drawerActiveTintColor: "#3c0a6b",
          drawerInactiveBackgroundColor: "transparent",
          drawerInactiveTintColor: "white",
          drawerStyle: { backgroundColor: "#593EFF" },
        }}
      >
        <Drawer.Screen
          name="Home"
          component={HomeScreen}
          options={{
            title: "Home",
            drawerLabel: "Home Screen",
            drawerIcon: ({ color, size }) => (
              <Ionicons name="person" color={color} size={size} />
            ),
          }}
        />
        <Drawer.Screen
          name="Contact"
          component={ContactScreen}
          options={{
            title: "Contact",
            drawerLabel: "Contact Screen",
            drawerIcon: ({ color, size }) => (
              <AntDesign name="contacts" color={color} size={size} />
            ),
          }}
        />
        <Drawer.Screen
          name="Setting"
          component={SettingScreen}
          options={{
            title: "Settings",
            drawerLabel: "Setting Screen",
            drawerIcon: ({ color, size }) => (
              <Ionicons name="settings" color={color} size={size} />
            ),
          }}
        />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

const styles = StyleSheet.create({});

Step 2: Let create react native custom directive component inside the components having component namve CustomDrawer.jsx. In this custom directive we add profile image and takes all the drawer screens as props and add it inside the CustomDrawer.jsx

import {
  StyleSheet,
  Text,
  View,
  ImageBackground,
  Image,
  TouchableOpacity,
} from "react-native";
import React from "react";
import {
  DrawerContentScrollView,
  DrawerItemList,
} from "@react-navigation/drawer";
import { Ionicons } from "@expo/vector-icons";

const CustomDrawer = (props) => {
  return (
    <View style={styles.container}>
      <DrawerContentScrollView {...props}>
        <ImageBackground
          source={require("../assets/menu-background.jpg")}
          style={styles.menuBackgroundImage}
        >
          <View style={styles.profileContainer}>
            <Image
              source={require("../assets/profile-image.jpg")}
              style={styles.profileImg}
            />
            <Text style={styles.profileName}>Mr. Jena Rosa</Text>
          </View>
          <View style={styles.logoutContainer}>
            <Ionicons name="log-out" color="white" size={22} />
            <Text style={styles.logoutText}>Sign Out</Text>
          </View>
        </ImageBackground>
        <View style={styles.drawerItemList}>
          <DrawerItemList {...props} />
        </View>
      </DrawerContentScrollView>
      <View style={styles.footerContainer}>
        <TouchableOpacity
          onPress={() => {}}
          style={({ pressed }) => [
            styles.pressedFooterMenuItem,
            { backgroundColor: pressed ? "yellow" : "black" },
          ]}
        >
          <View style={styles.footerMenuItem}>
            <Ionicons name="share-social-outline" size={22} color="white" />
            <Text style={styles.footerMenuLabel}>Tell with Friend</Text>
          </View>
        </TouchableOpacity>

        <TouchableOpacity
          onPress={() => {}}
          style={({ pressed }) => [
            styles.pressedFooterMenuItem,
            { backgroundColor: pressed ? "black" : "white" },
          ]}
        >
          <View style={styles.footerMenuItem}>
            <Ionicons name="star" size={22} color="white" />
            <Text style={styles.footerMenuLabel}>Rate Us</Text>
          </View>
        </TouchableOpacity>
      </View>
    </View>
  );
};

export default CustomDrawer;

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  menuBackgroundImage: { 
    padding: 20 }
  ,
  profileContainer: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
  },
  profileImg: {
    height: 75,
    width: 75,
    borderRadius: 35,
  },

  profileName: {
    color: "#fff",
    fontSize: 18,
  },

  logoutContainer: {
    flexDirection: "row",
    justifyContent: "flex-end",
  },

  logoutText: {
    fontSize: 15,
    marginLeft: 5,
    color: "white",
  },

  drawerItemList: {
    flex: 1,
    paddingTop: 5,
  },
  footerContainer: {
    padding: 10,
    borderTopWidth: 1,
    borderTopColor: "#a0a0a0",
  },

  pressedFooterMenuItem: {
    paddingVertical: 15,
  },
  footerMenuItem: {
    flexDirection: "row",
    alignItems: "center",
    height: 40,
  },

  footerMenuLabel: {
    fontSize: 16,
    color: "white",
    marginLeft: 5,
  },
});

Conclusion:
In this tutorial, we had learn how to implement react native drawer using react native drawer. Overall, creating a custom drawer using react-native-drawer is a straightforward process that can provide a lot of value to mobile applications. By using this library, developers can easily create a custom navigation experience that fits the needs of their users. I hope you have got some idea about how to implement it.

React Native Drawers: Best Practices and Examples

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top