React Native Popup Menu – Over Flow Menu

Popup Menu

React Native Popup Menu – Over Flow Menu is the most common thing that we can see in Android applications. In the initial stage, the popup menu can be seen in the header only, but after the introduction of the material design, the popup menu can be seen in many places.

You can use the popup menu if you want to provide the number of options to select but don’t want to highlight them. Most developers use them when they provide 2-3 options to select and they don’t want to use the navigation drawer (Side Menu).

How to use Menu Component for Popup Menu

<Menu
  visible={visible}
  anchor={<Text onPress={showMenu}>Show menu</Text>}
  onRequestClose={hideMenu}
>
  <MenuItem onPress={hideMenu}>Menu item 1</MenuItem>
  <MenuItem onPress={hideMenu}>Menu item 2</MenuItem>
  <MenuItem disabled>Disabled item</MenuItem>
  <MenuDivider />
  <MenuItem onPress={hideMenu}>Menu item 4</MenuItem>
</Menu>

In this example, You will see how to generate the popup menu from the header or from anywhere. So let’s get started.

To Make a React Native App

Getting started with React Native will help you to know more about the way you can make a React Native project. We are going to use react native command line interface to make our React Native App.

If you have previously installed a global react-native-cli package, please remove it as it may cause unexpected issues:

npm uninstall -g react-native-cli @react-native-community/cli

Run the following commands to create a new React Native project

npx react-native init ProjectName

If you want to start a new project with a specific React Native version, you can use the --version argument:

npx react-native init ProjectName --version X.XX.X

Note If the above command is failing, you may have old version of react-native or react-native-cli installed globally on your pc. Try uninstalling the cli and run the cli using npx.

This will make a project structure with an index file named App.js in your project directory.

Installation of Dependencies

To install any dependency first open the terminal and jump into your project

cd ProjectName

For the popup menu, you can use react-native-material-menu which provides Menu, MenuItem, and MenuDivider components to create an overflow menu

npm install react-native-material-menu --save

We need React Navigation for this example as we will use the header bar to set up the menu and also we will switch the screen.

To add react-navigation and other supporting dependencies,

1. Install react-navigation

npm install @react-navigation/native --save

2. Other supporting libraries react-native-screens and react-native-safe-area-context

npm install react-native-screens react-native-safe-area-context --save

react-native-screens package requires one additional configuration step to properly work on Android devices. Edit MainActivity.java file which is located in android/app/src/main/java/<your package name>/MainActivity.java.

Add the following code to the body of MainActivity class:

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(null);
}

and make sure to add the following import statement at the top of this file below your package statement:

import android.os.Bundle;

This change is required to avoid crashes related to the View state being not persisted consistently across Activity restarts.

3. For the Stack Navigator install

npm install @react-navigation/native-stack --save

Note: When you use a navigator (such as stack navigator), you’ll need to follow the installation instructions of that navigator for any additional dependencies. If you’re getting an error “Unable to resolve module”, you need to install that module in your project.

You might get warnings related to peer dependencies after installation. They are usually caused by incorrect version ranges specified in some packages. You can safely ignore most warnings as long as your app builds.

CocoaPods Installation

Please use the following command to install CocoaPods

npx pod-install

Project Structure

To start with this Example you need to create a pages directory in your project, under this pages directory create FirstPage.js, SecondPage.js, and CustomMaterialMenu.js

popup_menu_structure

App.js will have our Stack Navigator which is like an index file of our application. FirstPage.js and SecondPage.js will be the first and second screens of the application. We will use CustomMaterialMenu.js as a custom popup menu component.

Code for Popup Menu

Now Open App.js in any code editor and replace the code with the following code

App.js

// React Native Popup Menu – Over Flow Menu
// https://aboutreact.com/react-native-popup-menu/

import * as React from 'react';

import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';

import FirstPage from './pages/FirstPage';
import SecondPage from './pages/SecondPage';
//import our Custom Icon menu component
import CustomMaterialMenu from './pages/CustomMaterialMenu';

const Stack = createNativeStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="FirstPage"
        screenOptions={({route, navigation}) => ({
          headerRight: () => (
            <CustomMaterialMenu
              menuText="Menu"
              textStyle={{color: 'white'}}
              navigation={navigation}
              route={route}
              isIcon={true}
            />
          ),
        })}>
        <Stack.Screen
          name="FirstPage"
          component={FirstPage}
          options={{
            title: 'First Page', //Set Header Title
            headerStyle: {
              backgroundColor: '#f4511e', //Set Header color
            },
            headerTintColor: '#fff', //Set Header text color
            headerTitleStyle: {
              fontWeight: 'bold', //Set Header text style
            },
          }}
        />
        <Stack.Screen
          name="SecondPage"
          component={SecondPage}
          options={{
            title: 'Second Page', //Set Header Title
            headerStyle: {
              backgroundColor: '#f4511e', //Set Header color
            },
            headerTintColor: '#fff', //Set Header text color
            headerTitleStyle: {
              fontWeight: 'bold', //Set Header text style
            },
          }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

Open pages/FirstPage.js in any code editor and replace the code with the following code.

FirstPage.js

// React Native Popup Menu – Over Flow Menu
// https://aboutreact.com/react-native-popup-menu/

import * as React from 'react';
import {Button, View, Text, SafeAreaView} from 'react-native';
import CustomMaterialMenu from './CustomMaterialMenu';

const FirstPage = ({navigation, route}) => {
  return (
    <SafeAreaView style={{flex: 1}}>
      <View style={{flex: 1, padding: 16}}>
        <View
          style={{
            flex: 1,
            alignItems: 'center',
            justifyContent: 'center',
          }}>
          <Text
            style={{
              fontSize: 25,
              textAlign: 'center',
              marginBottom: 16,
            }}>
            This is the First Page of the app
          </Text>
          <Button
            onPress={() => navigation.navigate('SecondPage')}
            title="Go to Second Page"
          />
          <CustomMaterialMenu
            menuText="Show Menu"
            textStyle={{
              fontSize: 25,
              marginTop: 16,
              color: 'red',
            }}
            navigation={navigation}
            route={route}
            isIcon={false}
          />
        </View>
        <Text
          style={{
            fontSize: 18,
            textAlign: 'center',
            color: 'grey',
          }}>
          Popup Menu – Over Flow Menu
        </Text>
        <Text
          style={{
            fontSize: 16,
            textAlign: 'center',
            color: 'grey',
          }}>
          www.aboutreact.com
        </Text>
      </View>
    </SafeAreaView>
  );
};

export default FirstPage;

Open pages/SecondPage.js in any code editor and replace the code with the following code.

SecondPage.js

// React Native Popup Menu – Over Flow Menu
// https://aboutreact.com/react-native-popup-menu/

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

const SecondPage = ({navigation}) => {
  return (
    <SafeAreaView style={{flex: 1}}>
      <View style={{flex: 1, padding: 16}}>
        <View
          style={{
            flex: 1,
            alignItems: 'center',
            justifyContent: 'center',
          }}>
          <Text
            style={{
              fontSize: 25,
              textAlign: 'center',
              marginBottom: 16,
            }}>
            This is Second Page of the App
          </Text>
          <Button
            title="Go back"
            onPress={() => navigation.goBack()}
          />
        </View>
        <Text
          style={{
            fontSize: 18,
            textAlign: 'center',
            color: 'grey',
          }}>
          Popup Menu – Over Flow Menu
        </Text>
        <Text
          style={{
            fontSize: 16,
            textAlign: 'center',
            color: 'grey',
          }}>
          www.aboutreact.com
        </Text>
      </View>
    </SafeAreaView>
  );
};

export default SecondPage;

Open pages/CustomMaterialMenu in any code editor and replace the code with the following code.

CustomMaterialMenu.js

// React Native Popup Menu – Over Flow Menu
// https://aboutreact.com/react-native-popup-menu/

import React, {useState} from 'react';
//import react in our code.
import {View, Text, Image, TouchableOpacity} from 'react-native';
//import all the components we are going to use.
import {Menu, MenuItem, MenuDivider} from 'react-native-material-menu';
//import menu and menu item

const CustomMaterialMenu = ({isIcon, menuText, textStyle, route, navigation}) => {
  const [visible, setVisible] = useState(false);

  const hideMenu = () => setVisible(false);

  const showMenu = () => setVisible(true);

  return (
    <View>
      <Menu
        visible={visible}
        anchor={isIcon ? (
          <TouchableOpacity onPress={showMenu}>
            <Image
              source={{
                uri:
                  'https://raw.githubusercontent.com/AboutReact/sampleresource/master/menu_icon.png',
              }}
              style={{width: 30, height: 30}}
            />
          </TouchableOpacity>
        ) : (
          <Text
            onPress={showMenu}
            style={textStyle}>
            {menuText}
          </Text>
        )}
        onRequestClose={hideMenu}
      >
        {route.name === 'FirstPage' ? (
          <MenuItem
            onPress={() => {
              navigation.navigate('SecondPage');
              hideMenu();
            }}>
            Go to second Page
          </MenuItem>
        ) : null}
        {route.name === 'SecondPage' ? (
          <MenuItem
            onPress={() => { 
              navigation.navigate('FirstPage');
              hideMenu();
            }}>
            Go to first Page
          </MenuItem>
        ) : null}
        <MenuItem onPress={hideMenu}>
          Demo Option
        </MenuItem>
        <MenuItem disabled>Disabled option</MenuItem>
        <MenuDivider />
        <MenuItem onPress={hideMenu}>
          Option After Divider
        </MenuItem>
      </Menu>
    </View>
  );
};

export default CustomMaterialMenu;

To Run the React Native App

Open the terminal again and jump into your project using.

cd ProjectName

1. Start Metro Bundler

First, you will need to start Metro, the JavaScript bundler that ships with React Native. To start Metro bundler run following command:

npx react-native start

Once you start Metro Bundler it will run forever on your terminal until you close it. Let Metro Bundler run in its own terminal. Open a new terminal and run the application.

2. Start React Native Application

To run the project on an Android Virtual Device or on real debugging device:

npx react-native run-android

or on the iOS Simulator by running (macOS only)

npx react-native run-ios

Output Screenshots

                
      

Output in Online Emulator

That was the React Native Popup Menu. If you have any doubts or want to share something about the topic you can comment below or contact us here. There will be more posts coming soon. Stay tuned!

Hope you liked it. 🙂

8 thoughts on “React Native Popup Menu – Over Flow Menu”

    • You can use style for the menu item styling and textStyle for the menu item text styling
      Ex.

      <MenuItem
        // For the menu item style
        style={{ backgroundColor: 'blue' }}
        // For the menu item text style
        textStyle={{ color: 'green' , fontSize: 20}}
        onPress={() => {
          ......
        }}
      >
        Go to second Page
      </MenuItem>
      Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.