I am creating a react native application where I have a component app header that has a menu icon and when we press that the drawer should open but it is giving error that -
ERROR TypeError: navigation.toggleDrawer is not a function (it is undefined), js engine: hermes
Here is that component where I am using toggleDrawer() -
import { View, Text, StyleSheet, Image, TouchableOpacity } from 'react-native'
import React from 'react'
import { widthPercentageToDP as wp } from 'react-native-responsive-screen'
import { background_color, light_red, primary_color } from '../util/Colors'
import Ionicons from 'react-native-vector-icons/Ionicons'
import AntDesign from 'react-native-vector-icons/AntDesign'
import { useNavigation } from '@react-navigation/native'
export default function AppHeader({screenName}) {
const navigation=useNavigation();
const handleWallet=()=>{
navigation.navigate('Wallet');
}
const handleLanguage=()=>{
}
const handleSupport=()=>{
navigation.navigate('Customer Support')
}
const handleMenu=()=>{
navigation.toggleDrawer();
}
return (
<View style={styles.container}>
<TouchableOpacity onPress={handleMenu}>
<Ionicons name='menu' size={30} color={background_color}/>
</TouchableOpacity>
<Text style={styles.title}>{screenName}</Text>
<View style={styles.sideIcon}>
<TouchableOpacity onPress={handleWallet}>
<Image source={require('../Assets/wallet.png')} style={{ tintColor: background_color, width: 24, height:24 }} />
</TouchableOpacity>
<TouchableOpacity onPress={handleLanguage}>
<Image source={require('../Assets/language.png')} style={{ tintColor: background_color, width: 24, height:24 }} />
</TouchableOpacity>
<TouchableOpacity onPress={handleSupport}>
<Image source={require('../Assets/support.png')} style={{ tintColor: background_color, width: 24, height:24 }} />
</TouchableOpacity>
</View>
</View>
)
}
const styles=StyleSheet.create({
container:{
width:wp(100),
height:55,
backgroundColor:primary_color,
alignItems:"center",
flexDirection:"row",
paddingHorizontal:20,
gap:20,
marginBottom:8
},
title:{
color:background_color,
fontSize:18,
fontWeight:"bold"
},
sideIcon:{
position:"absolute",
right:0,
gap:18,
flexDirection:"row",
alignItems:"center",
marginRight:20
}
})
And also I have two more buttons wallet and customer support they are also not working and showing error -
The action 'NAVIGATE' with payload {"name":"Customer Support"} was not handled by any navigator.
Do you have a screen named 'Customer Support'?
If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.
This is a development-only warning and won't be shown in production.
According to me my Navigation is set up correctly here is Navigation.js -
import {Image} from 'react-native'
import React, { useEffect, useState } from 'react'
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import LogInviaPhone from '../Screens/LogInviaPhone';
import LogInviaEmail from '../Screens/LogInviaEmail';
import OTPScreen from '../Screens/OTPScreen';
import OTPScreenEmail from '../Screens/OTPScreenEmail';
import HomeScreen from '../Screens/HomeScreen';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Call from '../Screens/Call';
import Live from '../Screens/Live';
import Chat from '../Screens/Chat';
import Pooja from '../Screens/Pooja';
import FontAwesome from 'react-native-vector-icons/FontAwesome'
import Feather from 'react-native-vector-icons/Feather'
import Ionicons from 'react-native-vector-icons/Ionicons'
import AntDesign from 'react-native-vector-icons/AntDesign'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
import Foundation from 'react-native-vector-icons/Foundation'
import { background_color, primary_color, secondary_color } from '../util/Colors';
import History from '../Screens/History';
import Wallet from '../Screens/Wallet';
import Favorite from '../Screens/Favorite';
import Refer from '../Screens/Refer';
import FreeService from '../Screens/FreeService';
import AstrologerRegistration from '../Screens/AstrologerRegistration';
import CustomerSupport from '../Screens/CustomerSupport';
import Mall from '../Screens/Mall';
import Settings from '../Screens/Settings';
import MyFollowing from '../Screens/MyFollowing';
import CustomDrawer from './CustomDrawer';
import { appName } from '../util/AppDetails';
// import DeviceInfo from 'react-native-device-info';
// import * as RNLocalize from 'react-native-localize';
// import { getCountry } from "react-native-localize";
// import ISO3166 from 'iso-3166-1-alpha-2';
// import {NetworkInfo} from 'react-native-network-info';
// import axios from 'axios'
import { widthPercentageToDP as wp } from 'react-native-responsive-screen';
import Share from '../Screens/Share';
import RateUs from '../Screens/RateUs';
import UserDetails from '../Screens/UserDetails';
import AppHeader from '../Components/AppHeader';
import AsyncStorage from '@react-native-async-storage/async-storage';
const Stack=createNativeStackNavigator();
const Tab=createBottomTabNavigator();
const Drawer=createDrawerNavigator();
const MainTab=()=>{
return(
<Tab.Navigator screenOptions={{
tabBarStyle:{
backgroundColor:background_color,
height:55,
paddingBottom:5,
paddingTop:5,
paddingHorizontal:3
},
tabBarActiveTintColor:"black",
tabBarLabelStyle:{
fontSize:12
},
headerShown:false
}}>
<Tab.Screen name='Home' component={HomeScreen} options={{
tabBarIcon:({ color, size }) => (<Feather name="home" size={20} color={color} />),
}}/>
<Tab.Screen name='Call' component={Call} options={{
tabBarIcon:({ color, size }) => (<Ionicons name="call-outline" size={20} color={color} />),
}}/>
<Tab.Screen name='Live' component={Live} options={{
tabBarIcon:({ color, size }) => (<Feather name="video" size={20} color={color} />),
}}/>
<Tab.Screen name='Chat' component={Chat} options={{
tabBarIcon:({ color, size }) => (<Ionicons name="chatbubbles-outline" size={20} color={color} />),
}}/>
<Tab.Screen name='Pooja' component={Pooja} options={{
tabBarIcon: ({ color, size }) => (
<Image source={require('../Assets/kalash.png')} style={{ tintColor: color, width: 22, height: 22 }} />
)
}}/>
<Tab.Screen name='Mall' component={Mall} options={{
tabBarIcon: ({ color, size }) => (<MaterialCommunityIcons name="shopping" size={20} color={color} />)
}}/>
</Tab.Navigator>
)
}
const MainDrawer=({navigation})=>{
return(
<Drawer.Navigator screenOptions={{
drawerContentStyle:{
height:10,
},
drawerLabelStyle:{
marginVertical:-8,
paddingLeft:10,
textAlign:"left",
marginLeft:-15,
},
drawerStyle:{
width:wp(80)
},
drawerActiveBackgroundColor:secondary_color,
drawerActiveTintColor:"black",
headerShown:false
}}
drawerContent={props=> <CustomDrawer {...props}/>}>
<Drawer.Screen name='Home Screen' component={MainTab} options={{
title:" Home",
drawerIcon:({ color, size }) => (<Foundation name="home" size={20} color={color} />),
}}/>
<Drawer.Screen name='Chat' component={Chat} options={{
title:"Chat with Astrologer",
drawerIcon:({ color, size }) => (<Ionicons name="chatbubbles" size={20} color={color} />),
}}/>
<Drawer.Screen name='Call' component={Call} options={{
title:"Call Astrologer",
drawerIcon:({ color, size }) => (<Ionicons name="call" size={20} color={color} />)
}}/>
<Drawer.Screen name='Live' component={Live} options={{
title:"Astrologer Live",
drawerIcon:({ color, size }) => (<Ionicons name="videocam" size={20} color={color} />)
}}/>
<Drawer.Screen name='Pooja' component={Pooja} options={{
title:"Book a Pooja",
drawerIcon:({ color, size }) => (
<Image source={require('../Assets/kalash.png')} style={{ tintColor: color, width: 20, height: size }} />
)
}}/>
<Drawer.Screen name='History' component={History} options={{
title:"Order History",
drawerIcon:({ color, size }) => (<MaterialIcons name="history" size={20} color={color} />)
}}/>
<Drawer.Screen name='Wallet' component={Wallet} options={{
title:"Wallet Transaction",
drawerIcon:({ color, size }) => (<Ionicons name="wallet" size={20} color={color} />)
}}/>
<Drawer.Screen name='Favorite' component={Favorite} options={{
drawerIcon:({ color, size }) => (<MaterialIcons name="favorite" size={20} color={color} />)
}}/>
<Drawer.Screen name='Refer' component={Refer} options={{
title:"Refer to Friend",
drawerIcon:({ color, size }) => (<MaterialCommunityIcons name="share" size={20} color={color} />)
}}/>
<Drawer.Screen name='Astro Mall' component={Mall} options={{
drawerIcon:({ color, size }) => (<MaterialCommunityIcons name="shopping" size={20} color={color} />)
}}/>
<Drawer.Screen name='My Followings' component={MyFollowing} options={{
drawerIcon:({ color, size }) => (
<Image source={require('../Assets/following.png')} style={{ tintColor: color, width: 20, height: 20 }} />
)
}}/>
<Drawer.Screen name='Customer Support' component={CustomerSupport} options={{
drawerIcon:({ color, size }) => (<AntDesign name="customerservice" size={20} color={color} />)
}}/>
<Drawer.Screen name='Free Service' component={FreeService} options={{
drawerIcon:({ color, size }) => (
<Image source={require('../Assets/free.png')} style={{ tintColor: color, width: 20, height: 20 }} />
)
}}/>
<Drawer.Screen name='Register as Astrologer' component={AstrologerRegistration} options={{
title:" Register as Astrologer",
drawerIcon:({ color, size }) => (<FontAwesome name="user" size={20} color={color} />)
}}/>
<Drawer.Screen name='Settings' component={Settings} options={{
drawerIcon:({ color, size }) => (<Ionicons name="settings-sharp" size={20} color={color} />)
}}/>
<Drawer.Screen name='Share' component={Share} options={{
drawerIcon:({ color, size }) => (<Ionicons name="share-social" size={20} color={color} />)
}}/>
<Drawer.Screen name='Rate Us' component={RateUs} options={{
drawerIcon:({ color, size }) => (<Feather name="star" size={20} color={color} />)
}}/>
</Drawer.Navigator>
)
}
export default function Navigation() {
const [isAuthorized, setIsAuthorized] = useState(false);
const [country,setCountry]=useState(null);
useEffect(()=>{
AsyncStorage.getItem('persist:root').then((data) => {
if (data) {
const persistedState = JSON.parse(JSON.parse(data).auth);
setIsAuthorized(persistedState.isAuthenticated);
}
});
const fetchCountry=async()=>{
const request = await fetch("https://ipinfo.io/json?token=6cae93b1bf8907")
const jsonResponse = await request.json()
console.log(jsonResponse.ip, jsonResponse.country)
setCountry(jsonResponse.country)
}
fetchCountry();
},[]);
useEffect(() => {
console.log("Country ",country); // Log the country name whenever it changes
}, [country]);
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{
headerShown:false
}}>
{country === 'IN' ? (
<Stack.Screen name='Phone Login' component={LogInviaPhone} />
) : (
<Stack.Screen name='Email Login' component={LogInviaEmail} />
)}
<Stack.Screen name='OTP Phone' component={OTPScreen} />
<Stack.Screen name='Main Drawer' component={MainDrawer} />
<Stack.Screen name='OTP Email' component={OTPScreenEmail} />
<Stack.Screen name='Home Screen' component={MainTab} />
<Stack.Screen name='User Details' component={UserDetails} options={{
headerShown:true,
title:"Profile"
}}/>
<Stack.Screen name='Header' component={AppHeader}/>
</Stack.Navigator>
</NavigationContainer>
)
}
What should I do I tried navigation prop and useNavigation both It was working earlier but suddenly started showing this error also I have to apply a condition here that if user has authorized then he should directly navigate to home screen but because of this navigation issue it is not working and I had to delete it.
As mentioned in docs, this does not work.
I have created an example for my solution approach.