I’m having trouble with React Navigation on React Native Expo.
I have a bottom tab navigator, a separate screen (ProfileScreen), and a modal (ProfileLoginModal). The modal has a button that should redirect ProfileScreen. I put navigation.navigate("ProfileScreen")
in the modal, but it’s not doing anything, it’s not even giving me an error.
But if I change it to one of the screens in the bottom tab nav, for example navigation.navigate("Root", {screen: "HomeScreen})
, it works just fine. It just doesn’t work with screens outside the bottom tab nav.
Can anyone please help me understand what I’m doing wrong?
Navigation structure:
- BottomTabNavigator (Root)
- HomeScreen
- MenuScreen
- ProfileScreen
- ProfileLoginModal
Here is my navigation:
const Stack = createNativeStackNavigator<RootStackParamList>();
<NavigationContainer linking={LinkingConfiguration}>
<Stack.Navigator>
<Stack.Screen
name="Root"
component={BottomTabNavigator}
/>
<Stack.Screen
name="ProfileScreen" // ProfileScreen (destination)
component={ProfileScreen}
/>
<Stack.Group screenOptions={{ presentation: 'modal' }}>
<Stack.Screen
name="ProfileLoginModal" // Go to ProfileScreen from this modal
component={ProfileLoginModal}
/>
</Stack.Group>
</Stack.Navigator>
</NavigationContainer>
const BottomTab = createBottomTabNavigator<RootTabParamList>();
function BottomTabNavigator() {
return (
<BottomTab.Navigator
initialRouteName="HomeScreen"
screenOptions={...}
>
<BottomTab.Screen
name="HomeScreen"
component={HomeScreen}
options={...}
/>
<BottomTab.Screen
name="Menu"
component={MenuScreen}
options={...}
/>
</BottomTab.Navigator>
);
}
Typings:
export type RootStackParamList = {
Root: NavigatorScreenParams<RootTabParamList> | undefined;
ProfileScreen: undefined;
ProfileLoginModal: undefined;
};
export type RootStackScreenProps<Screen extends keyof RootStackParamList> =
NativeStackScreenProps<RootStackParamList, Screen>;
export type RootTabParamList = {
HomeScreen: undefined;
MenuScreen: undefined;
};
export type RootTabScreenProps<Screen extends keyof RootTabParamList> =
CompositeScreenProps<
BottomTabScreenProps<RootTabParamList, Screen>,
NativeStackScreenProps<RootStackParamList>
>;
Extra detail: I’d like ProfileScreen to have the bottom tab navigator visible, but with no corresponding tab icon.
I tried to make a nested navigator containing HomeScreen and ProfileScreen, like this
- BottomTabNavigator (Root)
- NestedHome
- HomeScreen
- ProfileScreen
- MenuScreen
- ProfileLoginModal
But I had a lot of issues as I didn’t know how to access double nested screens, if even possible (navigation.navigate('Root', screen: {'NestedHome', screen: {'ProfileScreen'}})
is clearly incorrect). I couldn’t find much info about it.
Thanks for your help.
2
Answers
I ended up going for the nested navigation that I tried before. The right function is
navigation.navigate("Root", {screen: "NestedHome", params: {screen: "ProfileScreen"}})
. From what I've seen, the docs don't go into details on this, and I only found out through a different SO thread.From HomeScreen you can navigate to ProfileScreen without nesting params :
ProfileLoginModal knows only about Root screen – if you want to navigate from ProfileLoginModal to ProfileScreen you need to use nesting params
You can access deep nested screens by specifying a params key