How to create a More-Popup Menu in React-Native


React-Native has pretty much all components you need, but the one that seems to be missing is a standard More-Popup Menu (also called DropDown Menu). I'm talking about the "three dots menu" you see in every application showing additional actions when you click on it:

react native more popup dropdown menu

There are already several NPM packages that try to recreate it by using buttons toggling a modal which renders a custom view representing the menu, but they all come with some layout problems, mostly when the More-Button is close to a border, it just overflows and looks hideous. If you look through the React-Native components or even search the doc for "Popup"/"Dropdown" nothing shows up. But ...


If you dig deep down the github rabbit hole as mentioned here, you can find an undocumented class that allows you to create Popups with its showPopupMenu method:

(UIManagerModule.showPopupMenu is only available for Android - there is currently no similar behavior for iOS.)

   * Show a PopupMenu.
   * @param reactTag the tag of the anchor view (the PopupMenu is displayed next to this view); this
   *        needs to be the tag of a native view (shadow views can not be anchors)
   * @param items the menu items as an array of strings
   * @param error will be called if there is an error displaying the menu
   * @param success will be called with the position of the selected item as the first argument, or
   *        no arguments if the menu is dismissed
  public void showPopupMenu(int reactTag, ReadableArray items, Callback error, Callback success) {
    mUIImplementation.showPopupMenu(reactTag, items, error, success);

The description is straight-forward, so let's see how to build a React component around it. We will use react-native-vector-icons to display an Icon with three vertical dots, and let the component take two properties:

  1. An actions array representing the menu items as strings
  2. An onPress callback handling clicks on these menu items: It gets called with the event name and the index of the pressed menu item. (The event names are either "itemSelected" or "dismissed".)

The implementation can be seen here.

import React, { Component, PropTypes } from 'react'
import { View, UIManager, findNodeHandle, TouchableOpacity } from 'react-native'
import Icon from 'react-native-vector-icons/MaterialIcons'

const ICON_SIZE = 24

export default class PopupMenu extends Component {
  static propTypes = {
    // array of strings, will be list items of Menu
    actions:  PropTypes.arrayOf(PropTypes.string).isRequired,
    onPress: PropTypes.func.isRequired

  constructor (props) {
    this.state = {
      icon: null

  onError () {
    console.log('Popup Error')

  onPress = () => {
    if (this.state.icon) {

  render () {
    return (
        <TouchableOpacity onPress={this.onPress}>
            ref={this.onRef} />

  onRef = icon => {
    if (!this.state.icon) {

Here's an example usage of this React-Native Popup Component:

  render () {
    return (
        <PopupMenu actions={['Edit', 'Remove']} onPress={this.onPopupEvent} />

  onPopupEvent = (eventName, index) => {
    if (eventName !== 'itemSelected') return
    if (index === 0) this.onEdit()
    else this.onRemove()