0

I'm trying to create a menu button in the header area. However, I don't know how to get the onPress navigation to work. I added a drawer navigator using React Navigation 6.x.

I want to show drawer when i press on Menu Icon. the problem I am having is that props.navigation.openDrawer() does not work

https://source--react-navigation-docs.netlify.app/docs/drawer-based-navigation

                     App.tsx
import 'react-native-gesture-handler';
import * as React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import{createDrawerNavigator} from '@react-navigation/drawer'
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Main from './src/screens/main';

const Stack = createNativeStackNavigator();
const Drawer = createDrawerNavigator();

const MyDrawer = () =>{
  return (
    <NavigationContainer>
    <Drawer.Navigator initialRouteName="Main"
      screenOptions={{
        headerShown: false
      }}
      >

        <Drawer.Screen
          name="Main"
          component={Main}  
        />


   </Drawer.Navigator>
    </NavigationContainer>
  );
};


export default MyDrawer;

     src-> components->header->my_header.js

import MCIcon from 'react-native-vector-icons/MaterialCommunityIcons'
import MIcon from 'react-native-vector-icons/MaterialIcons'
import { useNavigation } from '@react-navigation-hooks';

const My_Header = (props) => {
   const {navigate,goBack, toggleDrawer} = useNavigation();

    const Main_Header =()=>{
        return(
            <Header style={styles.bg_red} androidStatusBarColor="#ef394e">
                 

                <Right style={styles.row}>
                    {
                        props.head_page_name?
                            <Text style={styles.texth2}>
                                {props.head_page_name}
                            </Text>
                        :
                            <Text style={styles.texth1}>
                                
                            </Text>
                    }
                    
                    {
                        props.right_btn=='back'?
                            <Ripple style={styles.btn} onPress={()=>goBack(null)} >
                                <MIcon name='arrow-back' style={[styles.icon,{rotation:180}]} />
                            </Ripple>
                        :
                            <Ripple style={styles.btn} onPress={()=>toggleDrawer()} >
                                <MCIcon name='menu' style={styles.icon} />
                            </Ripple>
                    }
                </Right>
            </Header>
        )
    }

I want to replace

<Ripple style={styles.btn} onPress={()=>toggleDrawer()} >

to

<Ripple style={styles.btn} onPress={()=>props.navigation.openDrawer()} >

my_header.js

App.tsx

error

But it doesn't work, Can you please help me how can convert code .

I changed the code, but still when I click on menu icon doesn't show anything.Thank you for your attention

           src->screens->DrawerContent

import {StyleSheet, Text, View} from 'react-native';
import React from 'react';
  import {
    DrawerContentScrollView,
    DrawerItemList,
    DrawerItem,
  } from '@react-navigation/drawer';


const DrawerContent = (props)=>{
    const {navigation} = props;
return(
  <DrawerContentScrollView {...props}>
  <View>
  <Text  onPress={() => navigation.navigate('Main')}>
        Home
      </Text>
  </View>
  </DrawerContentScrollView>

  );
};

export default React.memo(DrawerContent)
------------------------------------------------------
                   App.tsx

import 'react-native-gesture-handler';
import * as React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import{createDrawerNavigator} from '@react-navigation/drawer'
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Main from './src/screens/main';
import DrawerContent from './src/screens/DrawerContent';
const Stack = createNativeStackNavigator();
const Drawer = createDrawerNavigator();
const MyStack = () => {
  return (
    <NavigationContainer>
       <Stack.Navigator
      initialRouteName="Main"
      screenOptions={{
        headerShown: false
      }}
    >
        <Stack.Screen
          name="Main"
          component={Main}
          
        />

       

      </Stack.Navigator>
    </NavigationContainer>
  );
};

const MyDrawer = () =>{
  return (
    <NavigationContainer>
    <Drawer.Navigator initialRouteName="Main"
      screenOptions={{
        headerShown: false }}
        drawerContent={props => <DrawerContent {...props} />}>

        <Drawer.Screen
          name="Main"
         component={Main}
          
        />
-------------------------------------------------------------
             src->component->header->my_header.js

import React from 'react'
import {ScrollView,Text,StyleSheet,TextInput} from 'react-native'
import { Container, Header, Left, Body, Right, Button, Title } from 'native-base';
import Ripple from 'react-native-material-ripple'
import MCIcon from 'react-native-vector-icons/MaterialCommunityIcons'
import MIcon from 'react-native-vector-icons/MaterialIcons'
import { useNavigation } from '@react-navigation/native';


const My_Header = (props) => {
   const {navigate,goBack} = useNavigation();
   const openDrawer = () =>{
    navigate.openDrawer();
   };
   

    const Main_Header =()=>{
        return(
            <Header style={styles.bg_red} androidStatusBarColor="#ef394e">
                  <Left style={styles.row}>
                    <Ripple style={styles.btn} onPress={()=>navigate('Shop_cart')}>
                        <MCIcon name='cart' style={styles.icon}/>
                    </Ripple>
                    <Ripple style={styles.btn} onPress={()=>navigate('Search')}>
                        <MIcon name='search' style={styles.icon}/>
                    </Ripple>
                </Left>

                <Right style={styles.row}>
                    {
                        props.head_page_name?
                            <Text style={styles.texth2}>
                                {props.head_page_name}
                            </Text>
                        :
                            <Text style={styles.texth1}>
                             
                            </Text>
                    }
                    
                    {
                        props.right_btn=='back'?
                            <Ripple style={styles.btn} onPress={()=>goBack(null)} >
                                <MIcon name='arrow-back' style={[styles.icon,{rotation:180}]} />
                            </Ripple>
                        :
                            <Ripple style={styles.btn}  >
                                <MCIcon name='menu' style={styles.icon} onPress={openDrawer} />
                            </Ripple>
                    }
                </Right>
            </Header>
        )
    }

source code: https://github.com/P-MBD/shopdroid/tree/Master

revised code

Output

node.js output

  • As you are using function components instead of class components remove the this reference ```this.props.navigation.openDrawer() -> props.navigation.openDrawer()``` – Michael Bahl Jun 17 '23 at 12:13
  • Thanks, I edited but "Uncaught Error cannot read property openDrawer". Also similar question https://stackoverflow.com/questions/59342648/react-native-drawer-navigation-how-to-open-drawer-by-clicking-custom-button-in but class base not function base – Parinaz Mobedi Jun 17 '23 at 14:56
  • according to https://stackoverflow.com/questions/71211821/how-can-i-add-an-onpress-event-listener-to-a-drawer-navigation-item-in-react-nat can't add this event listener directly on the screen component, I created the component CustomDrawer but I still need help – Parinaz Mobedi Jun 18 '23 at 03:36

1 Answers1

0

You can use useNavigation hook, check my example

import * as React from 'react';
import { Button, View, Image, Pressable } from 'react-native';
import { createDrawerNavigator, DrawerActions } from '@react-navigation/drawer';
import { NavigationContainer, useNavigation } from '@react-navigation/native';

function HomeScreen() {
  const navigation = useNavigation();

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button
        onPress={() => navigation.navigate('Notifications')}
        title="Go to notifications"
      />
      <Button
        onPress={() => navigation.openDrawer()}
        title="Open close drawer"
      />
    </View>
  );
}

function NotificationsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button onPress={() => navigation.goBack()} title="Go back home" />
    </View>
  );
}

const Drawer = createDrawerNavigator();

function CustomHeader() {
  const navigation = useNavigation();

  return (
    <Pressable
      onPress={() => {
        navigation.toggleDrawer();
      }}>
      <Image
        style={{ width: 50, height: 50 }}
        source={require('@expo/snack-static/react-native-logo.png')}
      />
    </Pressable>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator useLegacyImplementation initialRouteName="Home">
        <Drawer.Screen
          name="Home"
          component={HomeScreen}
          options={{ headerTitle: (props) => <CustomHeader {...props} /> }}
        />
        <Drawer.Screen name="Notifications" component={NotificationsScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}
Michael Bahl
  • 2,941
  • 1
  • 13
  • 16
  • thanks for your time and consideration. I am reading your code and try to edit my code. – Parinaz Mobedi Jun 19 '23 at 07:14
  • Hi, I edit the code but when i click toggle menu icon doesn't show anything. https://github.com/P-MBD/shopdroid/commit/59e66c393f4d3a8b3cc18f6e40c7785d40f7c579 also I create new react native project and install packege and copy your code. but cannot run , "reactNavigationOpenDrawer has stopped" https://github.com/P-MBD/reactNavigationOpenDrawer – Parinaz Mobedi Jun 20 '23 at 05:35
  • Ist seems that you have to currently to use ```useLegacyImplementation``` – Michael Bahl Jun 20 '23 at 10:10
  • Thank You for Your Help, I can run your example (https://github.com/P-MBD/reactNavigationOpenDrawer) and know work on main project. – Parinaz Mobedi Jun 21 '23 at 07:20