Stack navigator header button doesn't navigate to route on press - react-native

Here is my error: undefined is not an object (evaluating 'navigation.navigate')
My goal is to navigate to my Settings page when on click on my LeftHeader component in my StackNavigator:
Here is a snippet of my App.js file:
const FeedStackNav = () => {
return (
<Stack.Navigator>
<Stack.Screen
options={{
title: "",
headerLeft: ({ navigation }) => (
<Header>
<LeftHeader onPress={() => navigation.navigate("Settings")}>
<MenuIcon fill={"#C13B1E"} />
</LeftHeader>
</Header>
),
}}
name="Feed"
component={Feed}
/>
</Stack.Navigator>
);
};
And here is how I am rendering the Stack in my app:
<NavigationContainer theme={theme}>
<Stack.Navigator>
<Stack.Screen
options={{
headerShown: false,
}}
name=" "
component={TabNav}
/>
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
There has to be something wrong with my LeftHeader onPress function

Am adding just snippet of code to illustrate how to use navigation.navigate('screen') on header button
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}>
<Stack.Screen
name="Home"
component={HomeScreen}
options={({navigation, route}) => ({
headerRight: () => (
<TouchableOpacity onPress={() => alert('Just clicked!!')}>
<FontIcon
onPress={() => navigation.navigate('CreateSession')}
name="video-camera"
color={whitish}
size={25}
/>
</TouchableOpacity>
),
})}
/>
<Stack.Screen name="CreateSession" component={CreateSessionScreen} />
<Stack.Screen name="LiveSessions" component={LiveSession} />
</Stack.Navigator>
</NavigationContainer>
on above code observe the callback function used to get access to navigation and route props
options={({navigation, route}) => ({
headerRight: () => (
<TouchableOpacity onPress={() => alert('Just clicked!!')}>
<FontIcon
onPress={() => navigation.navigate('CreateSession')}
name="video-camera"
color={whitish}
size={25}
/>
</TouchableOpacity>
),
})}

Related

Independent stack navigation outside tab and drawer navigation in React-Native

I use
react-native:0.68.2
react-navigation/bottom-tabs:6.3.1
react-navigation/drawer:6.4.1
react-navigation/native:6.0.10
react-navigation/stack:6.2.1
And I have next navigation structure:
<Drawer.Navigator>
<Tab.Navigator>
<Stack.Navigator>
<Screen1>
<Screen2>
</Stack.Navigator>
</Tab.Navigator>
</Drawer.Navigator>
It looks like drawer slide menu from left side and bottom tabs on the main screen. You can see short video of it by next link
What do I want
I want to open new screen from Screen1 like independent screen (without tabs and drawer). It looks like new Activity in Android or new view controller in iOS.
you need to try this
const TabStack = () => {
return (
<Tab.Navigator
initialRouteName="LiveRate"
screenOptions={{
tabBarActiveBackgroundColor: colors.activeTabColor,
tabBarInactiveBackgroundColor: colors.inactiveTabColor,
tabBarStyle: {
backgroundColor: '#f46023',
height:60
},
}}>
<Tab.Screen
name="LiveRate"
component={LiveRateScreen}
options={{
tabBarLabel: () => {
return (<Text style={{color:'white', fontSize:12, marginBottom:5}}>Live Rate</Text>)
},
headerShown: false,
tabBarIcon: ({ focused }) => (
<Image
source={
focused
? Images.liverate
: Images.liverate
}
style={{
width: 30,
height: 30,
resizeMode:'contain'
// padding:5
}}
/>
),
}}
/>
<Tab.Screen
name="AboutUs"
component={AboutUsScreen}
options={{
tabBarLabel: () => {
return (<Text style={{color:'white', fontSize:12, marginBottom:5}}>About Us</Text>)
},
headerShown: false,
tabBarIcon: ({ focused, color, size }) => (
<Image
source={
focused
? Images.aboutus
: Images.aboutus
}
style={{
width: 30,
height: 30,
resizeMode:'contain'
// padding:5
}}
/>
),
}}
/>
<Tab.Screen
name="booking"
component={BookingNumberScreen}
options={{
tabBarLabel: () => {
return (<Text style={{color:'white', fontSize:12, marginBottom:5}}>Booking Number</Text>)
},
headerShown: false,
tabBarIcon: ({ focused, color, size }) => (
<Image
source={
focused
? Images.booking
: Images.booking
}
style={{
width: 30,
height: 30,
resizeMode:'contain'
}}
/>
),
}}
/>
<Tab.Screen
name="notification"
component={NotificationScreen}
options={{
tabBarLabel: () => {
return (<Text style={{color:'white', fontSize:12, marginBottom:5}}>Notification</Text>)
},
headerShown: false,
tabBarIcon: ({ focused, color, size }) => (
<Image
source={
focused
? Images.notificationbell
: Images.notificationbell
}
style={{
width: 30,
height: 30,
resizeMode:'contain'
}}
/>
),
}}
/>
</Tab.Navigator>
);
};
const NavigationUtil = () => {
return (
<NavigationContainer ref={navigationRef}>
<Stack.Navigator initialRouteName="SlpashScreen">
<Stack.Screen
name="tabStack"
component={TabStack} <----- you also pass your drawer stack
options={{headerShown: false}}
/>
<Stack.Screen
name="Registration"
component={RegistrationScreen}
options={{headerShown: false}}
/>
<Stack.Screen
name="SlpashScreen"
component={SlpashScreen}
options={{headerShown: false}}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
this is my code
hop it's working

Problem with React Navigation Bottom Tabs and Stack

I have 5 pages in bottomTab, and I want to navigate to others from these 5 pages. I looked at the docs in the official site of React navigation, wrote my code the same way, but it doesnt work.. I'm putting my code below, so you can have a look at it.
//This is my bottomTab
function Tabs(){
return(
<Tab.Navigator screenOptions={() => ({
tabBarActiveTintColor: '#fff',
tabBarInactiveTintColor: '#777',
headerTintColor:"#fff",
headerStyle:{
backgroundColor: '#000',
},
tabBarStyle: {
backgroundColor: '#000',
paddingBottom: 5,
paddingTop: 5,
},
})}>
<Tab.Screen
name='Historico' component={Historico}
options={{ tabBarIcon: ({ size, color }) => ( <AntDesign name='profile' size={size} color={color}/>)
}} />
<Tab.Screen
name='Relatorios'
component={Relatorios}
options={{ tabBarIcon: ({ size, color }) => (<AntDesign name='areachart' size={size} color={color}/> )
}} />
<Tab.Screen
name='Plus'
component={Plus}
options={{
tabBarLabel: '',
tabBarIcon: ({ size, color }) => (<AntDesign name='plus' size = {28} color={color}/> ),
headerShown: false
}} />
<Tab.Screen
name='Lembretes'
component={ShowLembretes}
options={{
tabBarLabel: 'Lembretes',
tabBarIcon: ({ size, color }) => (<AntDesign name='clockcircleo' size={size} color={color}/>)
}} />
<Tab.Screen
name='Mais'
component={Mais}
options={{ tabBarIcon: ({ size, color }) => (<AntDesign name='ellipsis1' size={size} color={color}/>)
}} />
</Tab.Navigator>
)
}
//These are my routes of my app, I put my `Tab` inside my `stack`
export default function Routes(){
return(
<NavigationContainer>
<Stack.Navigator initialRouteName="Tabs"> //Its `Tabs` just for development
<Stack.Screen name= "Preload" component= {Preload} options={{ headerShown: false}}/>
<Stack.Screen name= "Tabs" component={Tabs} options={{ headerShown: false }}/>
<Stack.Screen name= "Despesa" component={Despesa} />
<Stack.Screen name= "Serviço" component={Serviço} />
<Stack.Screen name= "Receita" component={Receita} />
<Stack.Screen name= "AddLembrete" component={AddLembrete} />
<Stack.Screen name= "Abastecimento" component={Abastecimento} />
<Stack.Screen name= "Veiculos" component={Veiculos} />
</Stack.Navigator>
</NavigationContainer>
)
}
export default function Plus({ navigation }){
return (
<TelaPlus style={estilos.tela}>
<View style={estilos.linha1}>//This is the way Im trying to navigate,is it wrong?
<Box onPress={()=> navigation.navigate('Despesa')}>
<MaterialCommunityIcons name="elevation-decline" size={24} color="white" />
<Texto>Despesa</Texto>
</Box>
<Box onPress={()=> navigation.navigate('Serviço')}>
<MaterialCommunityIcons name="car-wrench" size={24} color="white" />
<Texto>Serviço</Texto>
</Box>
<Box onPress={()=> navigation.navigate('Receita')}>
<MaterialCommunityIcons name="elevation-rise" size={24} color="white" />
<Texto>Receita</Texto>
</Box>
</View>
<View style={estilos.linha2} onPress={()=> navigation.navigate('Lembrete')}>
<Box style={estilos.box}>
<MaterialCommunityIcons name="clock-plus-outline" size={24} color="white" />
<Texto>Lembrete</Texto>
</Box>
<Box onPress={()=> navigation.navigate('Abastecimento')}>
<MaterialCommunityIcons name="gas-station" size={24} color="white" />
<Texto>Abastecimento</Texto>
</Box>
</View>
</TelaPlus>
)
};
Please, any help will be welcome! Thanks!
Sorry for my English, its not mt first language, still learning it too.
you can set tabLongPress act like tabPress
<BottomTab.Navigator
screenListeners={({ navigation }) => ({
tabLongPress: (e) => {
navigation.jumpTo(e.target.split('-')[0]);
},
})}
>
for more detail, check this link

The action 'NAVIGATE' with payload {"name":"ChatScreen"} was not handled by any navigator. Do you have a screen named 'ChatScreen'?

here is my App.js which is the entry point. i get the error The action 'NAVIGATE' with payload {"name":"ChatScreen"} was not handled by any navigator.
Do you have a screen named 'ChatScreen'?
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. and i have the ChatScreen in screens directory
import react from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import MainTabScreen from './scr/components/MainTabScreen';
import { DrawerContent } from './scr/components/DrawerContent';
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
{/* screenOptions={{headerStyle:{
backgroundColor: '#009387',
},
headerTintColor: '#fff',
headerTitleStyle:{
fontWeight: 'bold'
} */}
<Drawer.Navigator drawerContent={props => <DrawerContent {...props} />}>
<Drawer.Screen
options={{
headerShown: false
}}
name='md' component={MainTabScreen} />
{/* <Drawer.Screen name="Products" component={Products} /> */}
</Drawer.Navigator>
</NavigationContainer>
);
}
here is my MainTbScreen.js which contains the navigation
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs'
import Icon from 'react-native-vector-icons/Ionicons'
import HomeScreen from '../screens/Homescreen'
import Ministries from '../screens/Ministries'
import ProfileScreen from '../screens/ProfileScreen'
import { createNativeStackNavigator } from '#react-navigation/native-stack'
import ChatScreen from '../screens/ChatScreen';
const HomeStack = createNativeStackNavigator();
const DetailsStack = createNativeStackNavigator();
const Tab = createMaterialBottomTabNavigator();
const MainTabScreen = () => (
<Tab.Navigator
initialRouteName="Home"
activeColor="#fff"
>
<Tab.Screen
name="Home"
component={HomeStackScreen}
options={{
tabBarLabel: 'Home',
tabBarColor: '#009387',
tabBarIcon: ({ color }) => (
<Icon name="home" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Notifications"
component={DetailsStackScreen}
options={{
tabBarLabel: 'Chat',
tabBarColor: '#1f65ff',
tabBarIcon: ({ color }) => (
<Icon name="Messagebox" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Chat"
component={ChatScreen}
options={{
tabBarLabel: 'Profile',
tabBarColor: '#694fad',
tabBarIcon: ({ color }) => (
<Icon name="person" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Profile"
component={ProfileScreen}
options={{
tabBarLabel: 'Profile',
tabBarColor: '#d02860',
tabBarIcon: ({ color }) => (
<Icon name="ios-aperture" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
);
export default MainTabScreen;
const HomeStackScreen = ({navigation}) => (
<HomeStack.Navigator screenOptions={{
headerStyle: {
backgroundColor: '#009387',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold'
}
}}>
<HomeStack.Screen name="Home" component={HomeScreen} options={{
title:'Overview',
headerLeft: () => (
<Icon.Button name="ios-menu" size={25} backgroundColor="#009387" onPress={() => navigation.openDrawer()}></Icon.Button>
)
}} />
</HomeStack.Navigator>
);
const DetailsStackScreen = ({navigation}) => (
<DetailsStack.Navigator screenOptions={{
headerStyle: {
backgroundColor: '#1f65ff',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold'
}
}}>
<DetailsStack.Screen name="Details" component={Ministries} options={{
headerLeft: () => (
<Icon.Button name="ios-menu" size={25} backgroundColor="#1f65ff" onPress={() => navigation.openDrawer()}></Icon.Button>
)
}} />
</DetailsStack.Navigator>
);
You are navigating using ChatScreen but this is not the name that you have defined in the Screen inside the navigator's name prop.
Either, do
<Tab.Screen
name="ChatScreen"
component={ChatScreen}
options={{
tabBarLabel: 'Profile',
tabBarColor: '#694fad',
tabBarIcon: ({ color }) => (
<Icon name="person" color={color} size={26} />
),
}}
/>
or navigation.navigate("Chat") while leaving name="Chat".

How to solve navigation.navigate error when set TouchableOpacity in StackScreen header options?

I want to add a button(icon) on stack header(on right side). On-click it goes to that page but it's not working. It appears 'undefined is not an object (evaluating 'navigation.navigate')'.
Below is my code:
<Stack.Navigator>
<Stack.Screen name="Page1" component={Page1} />
<Stack.Screen
name="Page2"
component={Page2}
options={{
headerRight: () => (
<View>
<TouchableOpacity
onPress={() => navigation.navigate('Page3')}>
<Image source={require('../assets/image.png')} />
</TouchableOpacity>
</View>
)
}}
/>
<Stack.Screen name="Page4" component={Page4} />
<Stack.Screen name="Page5" component={Page5} />
</Stack.Navigator>
You can pass the navigation from the options to the headerRight:
options={({navigation}) => ({
headerRight: () => (
...
),
})}
or useNavigation():
const navigation = useNavigation();
EDIT 2:
fixed your snack code and its working fine:
You had to add a stackScreen called 'MyorderStack' because you're trying to navigate to that.
<NavigationContainer independent={true}>
<Stack.Navigator screenOptions={{ headerTintColor: 'blue' }}>
<Stack.Screen name="Global Page" component={AppNavigator} options={{ headerShown: false }} />
<Stack.Screen name="DetailOne" component={DetailOne} options={({navigation}) => ({ headerBackTitleVisible: false, title: 'Global Page',
headerRight: () => (
<View style={{flexDirection: 'row',justifyContent: 'flex-end',width: '50%'}}>
<View style={{ marginRight: 10 }}>
<TouchableOpacity onPress={() => navigation.navigate('MyorderStack')}>
<Image source={require('./assets/shop.png')} style={styles.Image} />
</TouchableOpacity>
</View>
</View>
), headerTitleAlign:'center', headerTintColor:colors.primary
})}
/>
<Stack.Screen name="DetailTwo" component={DetailTwo} options={{headerBackTitleVisible: false, headerTitleAlign: 'center', title: 'Global Page', headerTintColor: colors.primary}} />
<Stack.Screen name="MyorderStack" component={MyorderStack} options={{headerBackTitleVisible: false, headerTitleAlign: 'center', title: 'Global Page', headerTintColor: colors.primary}} />
</Stack.Navigator>
</NavigationContainer>
Navigation is only defined within the screen's components. In your case, you can try useNavigation hook to navigate to different screen. Import it like:
import { useNavigation } from '#react-navigation/native';
and declare it like:
const navigation = useNavigation();
Then you it to your TouchableOpacity prop like onPress={() => navigation.navigate('Page3')}.
Hope this works for you. Thanks

react navigation 5 header is not shown

Using react navigation 5, I want to create a dynamic map for all my Drawer Screens, but the header is not shown with code:
<NavigationContainer>
<Drawer.Navigator
drawerContent={props => <DrawerContent {...props} />}>
{stackNavigItens.map((props, r) => (
<Drawer.Screen
key={r.name}
name={r.name}
component={({navigation}) => (
<Stack.Navigator
initialRouteName="Home"
headerMode="screen"
screenOptions={{
headerTitle: r.label,
headerStyle: {
backgroundColor: '#2e72e8',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
{...props}>
<Stack.Screen
name={r.name}
component={r.component}
options={{
title: r.label,
headerLeft: () => (
<Icon.Button
name="ios-menu"
size={25}
backgroundColor="#2e72e8"
onPress={() => {
navigation.openDrawer();
}}
/>
),
}}
{...props}
/>
</Stack.Navigator>
)}
{...props}
/>
))}
</Drawer.Navigator>
</NavigationContainer>
If I use every createStackNavigator in a const like below, and then call inside component of the Drawer the header shows correctly, I don't know Why ? I think maybe because of the {navigation} arrow function, but don't work too.
const HomeStackScreen = ({navigation}) => (
<HomeStack.Navigator
screenOptions={{
headerStyle: {
backgroundColor: '#2e72e8',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}>
<HomeStack.Screen
name="Home"
component={HomeScreen}
options={{
headerLeft: () => (
<Icon.Button
name="ios-menu"
size={25}
backgroundColor="#2e72e8"
onPress={() => {
navigation.openDrawer();
}}
/>
),
}}
/>
</HomeStack.Navigator> );