Building Custom Dynamic Drawer Navigation in React Native: Best Practices and Tips

Building Custom Dynamic Drawer Navigation in React Native: Best Practices and Tips

Create a custom drawer in React Native app using Expo, you can follow these steps:

Step 1: Create a new Expo project

Navigate to the directory where you want to create your new app and run the following command:

npx create-expo-app my-app

Step 2: Run the Expo development server

Navigate into the newly created project directory:

cd my-app

Start the development server by running:

npm start

This will launch the Expo development server, and you'll see a QR code in the terminal.

Step 3: Install the required packages in your React Native project

npm install @react-navigation/native
npm install react-native-screens react-native-safe-area-context

Step 4: install @react-navigation/drawer package

npm install @react-navigation/drawer

Step 5: Install the required packages

npm install react-native-gesture-handler react-native-reanimated

Step 6: Add react-native-reanimated/plugin as plugin in "babel.config.js"

react-native-reanimated/plugin

Step 7: Create files that will be displayed within the app drawer frame

a. Create the necessary components:

  • Inside your React Native project, create separate JavaScript files for each component that you want to display in the app drawer. For example, you can create HomeScreen.js file.

b. Define the content for each component:

  • In each component file, define the content that you want to display when the corresponding item is selected in the app drawer. This content can include UI elements, such as text, images, buttons, or any other desired components.

Try this example

import { StyleSheet, Text, View, TouchableOpacity } from "react-native";
import React from "react";
import { useNavigation } from "@react-navigation/native";

const HomeScreen = () => {
  const navigation = useNavigation();
  return (
    <View style={styles.container}>
      <TouchableOpacity
        onPress={() => navigation.openDrawer()}
        style={styles.DrawerButton}
      >
        <Text style={styles.ButtonText}> Drawer</Text>
      </TouchableOpacity>
    </View>
  );
};

export default HomeScreen;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  DrawerButton: {
    backgroundColor: "#000",
    paddingVertical: 8,
    paddingHorizontal: 20,
    borderRadius: 10,
  },
  ButtonText: {
    color: "#fff",
  },
});

Step 8: Create a "CustomDrawer" component

  • Create a Components folder in your React Native project

  • Inside Components folder create a file name "CustomDrawer.js"

  • Install react-native-vector-icons package

npm i react-native-vector-icons
  • Import DrawerContentScrollView and DrawerItemList from '@react-navigation/drawer'

Try this example

import {
  View,
  Text,
  ImageBackground,
  Image,
  TouchableOpacity,
  StyleSheet,
  Switch,
} from "react-native";
import {
  DrawerContentScrollView,
  DrawerItemList,
} from "@react-navigation/drawer";

import Ionicons from "react-native-vector-icons/Ionicons";

const CustomDrawer = (props) => {
  return (
    <View style={{ flex: 1 }}>
      <DrawerContentScrollView
        {...props}
        contentContainerStyle={{
          backgroundColor: "#9288F9",
          marginTop: -50,
          zIndex: 10,
        }}
      >
        <ImageBackground
          source={require("../assets/Images/background.jpg")}
          style={{ padding: 20 }}
        >
          <Image
            alt="Not find"
            source={require("../assets/Images/user.jpg")}
            style={styles.userAvatar}
          />
          <Text
            style={{
              color: "#fff",
              fontSize: 18,
              marginBottom: 5,
            }}
          >
            Name
          </Text>
        </ImageBackground>
        <View style={{ flex: 1, backgroundColor: "#fff", paddingTop: 10 }}>
          <DrawerItemList {...props} />
        </View>
      </DrawerContentScrollView>
      <View
        style={{
          borderTopWidth: 1,
          borderTopColor: "#ccc",
          // backgroundColor: colors.cardbackground,
        }}
      >
        <Text style={styles.preferences}>Preferences</Text>
        <View style={styles.switchTextContainer}>
          <Switch
            trackColor={{ false: "#767577", true: "#81b0ff" }}
            thumbColor="#f4f3f4"
            style={{ transform: [{ scaleX: 0.9 }, { scaleY: 0.9 }] }}
          />
          <Text
            style={{
              fontSize: 15,
            }}
          >
            Dark Theme
          </Text>
        </View>
      </View>
      <View style={{ padding: 20, borderTopWidth: 1, borderTopColor: "#ccc" }}>
        <TouchableOpacity onPress={() => {}} style={{ paddingVertical: 15 }}>
          <View style={{ flexDirection: "row", alignItems: "center" }}>
            <Ionicons name="share-social-outline" size={22} />
            <Text
              style={{
                fontSize: 15,

                marginLeft: 5,
              }}
            >
              Tell a Friend
            </Text>
          </View>
        </TouchableOpacity>
        <TouchableOpacity style={{ paddingVertical: 15 }}>
          <View style={{ flexDirection: "row", alignItems: "center" }}>
            <Ionicons name="exit-outline" size={22} />
            <Text
              style={{
                fontSize: 15,

                marginLeft: 5,
              }}
            >
              Sign Out
            </Text>
          </View>
        </TouchableOpacity>
      </View>
    </View>
  );
};

export default CustomDrawer;

const styles = StyleSheet.create({
  userAvatar: {
    height: 67.5,
    width: 67.5,
    borderRadius: 40,
    marginBottom: 10,
    marginTop: 30,
  },
  switchTextContainer: {
    flexDirection: "row",
    alignItems: "center",
    marginLeft: 7,
    paddingVertical: 5,
  },
  preferences: {
    fontSize: 16,
    color: "#ccc",
    paddingTop: 10,
    fontWeight: "500",
    paddingLeft: 20,
  },
  switchText: {
    fontSize: 17,
    color: "",
    paddingTop: 10,
    fontWeight: "bold",
  },
});

Step 9: Create an "AppStack.js" file

  • Import createDrawerNavigator from '@react-navigation/drawer'; To us drawer navigator.

  • Use "props" to import drawer contents from "CustomDrawer" Component

import React from "react";
import { createDrawerNavigator } from "@react-navigation/drawer";
import HomeScreen from "./Screens/HomeScreen";
import CustomDrawer from "./Components/CustomDrawer";
const Drawer = createDrawerNavigator();
const AppStack = () => {
  return (
    <Drawer.Navigator drawerContent={(props) => <CustomDrawer {...props} />}>
      <Drawer.Screen
        name="HomeScreen"
        component={HomeScreen}
        options={{ headerShown: false }}
      />
    </Drawer.Navigator>
  );
};

export default AppStack;

Step 10: Config "App.js" file

  • Import NavigationContainer from "@react-navigation/native"

  • Import "react-native-gesture-handler"

  • Import "AppStack.js" file

import { NavigationContainer } from "@react-navigation/native";

import "react-native-gesture-handler";

import AppStack from "./AppStack";

export default App = () => {
  return (
    <NavigationContainer>
      <AppStack />
    </NavigationContainer>
  );
};

Restart the Expo development server, and you'll discover an amazing custom drawer frame waiting for you!

You can explore the source code of this project on GitHub to check out the amazing custom drawer frame.