7
votes

I want to display HeaderLeft Menu icon globally in all screens. When I click on Menu Icon, I need to display Drawer Menu. I use "OpenDrawer", "CloseDrawer" methods for open/close drawer menu.

But I am always getting "undefined is not a function (evaluating 'props.navigation.openDrawer()')". I also tried the following

props.navigation.dispatch(DrawerActions.openDrawer())
props.navigation.navigate(openDrawer())

But None of the above worked. Here is my partial code

const MenuButton = (props) => {
  return (
    <View>
      <TouchableOpacity onPress={() => { props.navigation.dispatch(DrawerActions.openDrawer())} }>
        <Text>Menu</Text>
      </TouchableOpacity>
    </View>
  )
};

const MyDrawerNavigator = createDrawerNavigator(
  {
    Wishist: {
      screen: wishlist
    },
  },
  {
    contentComponent: SideMenuScreen,
    drawerWidth: 200,
  }
);

const AppNavigator = createBottomTabNavigator({
  Home: {
    screen: createStackNavigator({
      Home: {
        screen: Home
      },
      Contact: {
        screen: Contact
      }
    },
    {
      defaultNavigationOptions: ({ navigation }) => ({
        headerStyle: {
          backgroundColor: 'white',
          borderWidth:0,
          borderBottomWidth:0
        },
        headerTitle: headerTitleNavigationOptions('HOME'),
        headerLeft: <MenuButton navigation={navigation}/>,
        headerRight: headerRightNavigatorOptions(navigation)
      })
    }),
    navigationOptions: ({ navigation }) => ({
      headerStyle: {
          backgroundColor: 'white',
          borderWidth:0,
          borderBottomWidth:0
      },
    }),
  }},
  {
    tabBarOptions: {
      showLabel: false,
      style: {
        backgroundColor: 'white',
        borderTopWidth:1
      }
    },
    initialRouteName: 'Home',
    tabBarComponent: TabBarBottom,
    tabBarPosition: 'bottom',
    animationEnabled: false,
    swipeEnabled: false
  }
);

const App = createAppContainer(AppNavigator);
2
You're sending the "navigation" directly to MenuButton. Try replace this "props.navigation.openDrawer()" with this "navigation.openDrawer()" - Ashwin Mothilal
Can't see MyDrawerNavigator declared in your main AppNavigator. Try making your drawerNavigator as your app container. - Nishant Nair

2 Answers

3
votes

you need to import the DrawerActions in your component from react-navigation-drawer as explained in the docs

DrawerActions is an object containing methods for generating actions specific to drawer-based navigators. Its methods expand upon the actions available in NavigationActions.

The following actions are supported:

  • openDrawer - open the drawer
  • closeDrawer - close the drawer
  • toggleDrawer - toggle the state, ie. switche from closed to open and vice versa

import { DrawerActions } from 'react-navigation-drawer';

this.props.navigation.dispatch(DrawerActions.openDrawer())

The react-navigation api do not provide more information, but you can consult the NavigationActions api reference for more information.

NavigationActions reference

All NavigationActions return an object that can be sent to the router using navigation.dispatch() method.

Note that if you want to dispatch react-navigation actions you should use the action creators provided in this library.

You need to import NavigationActions in your component and then you can dispatch your action with something like this.props.navigation.dispatch(navigateAction);

import { NavigationActions } from 'react-navigation';

const navigateAction = NavigationActions.navigate({
  routeName: 'Profile',

  params: {},

  action: NavigationActions.navigate({ routeName: 'SubProfileRoute' }),
});

this.props.navigation.dispatch(navigateAction);

also as explained from Ashwin Mothilal, make sure you are passing the navigation prop inside your component. For example you can run a console.warn(props) and immediatly see the result on the emulator. This is your component:

import { DrawerActions } from 'react-navigation-drawer';

const MenuButton = (props) => {
  return (
    <View>
      <TouchableOpacity onPress={() => {
          console.warn(props);
          props.navigation.dispatch(DrawerActions.openDrawer());
      }}>
        <Text>Menu</Text>
      </TouchableOpacity>
    </View>
  )
};
0
votes

At first, just console the props in Menu button and check if you get openDrawer or closeDrawer or any other method you are looking for then you can call it.