I am currently using a bottom Tab navigator with a Stack navigator nested inside of it.
Tabs.tsx:
<NavigationContainer>
<Tab.Navigator>
// other screens here
<Tab.Screen
name="Stack"
component={StackNavigator}
/>
</Tab.Navigator>
</NavigationContainer>
StackNavigator.tsx:
const StackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="First"
component={First}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Second"
component={Second}
options={{ headerShown: false }}
/>
</Stack.Navigator>
);
};
This was working fine, but since I wanted to hide the BottomTabNavigator in my “Second” screen I nested the Tab Navigator inside the StackNavigator as it is shown in the documentation.
Tabs.tsx after changes:
<NavigationContainer>
<Tab.Navigator>
// other screens here
<Tab.Screen
name="First"
component={First}
/>
</Tab.Navigator>
</NavigationContainer>
Stack.tsx after changes:
const StackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Tabs"
component={Tabs}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Second"
component={Second}
options={{ headerShown: false }}
/>
</Stack.Navigator>
);
};
Now I try to call a navigate function in my “First” component:
const First = ({ navigation }) => {
return (
<View style={styles.container}>
//other elements
<FAB
icon="plus"
style={styles.fab}
onPress={() => navigation.navigate("Tabs", {screen: "Second"})}
/>
);
};
But I get this error on pressing the button:
The action 'NAVIGATE' with payload {"name":"Tabs","params":{"screen":"Second"}} was not handled by any navigator.
Do you have a screen named 'Tabs'?
Since I read here that other people had problems with conditional rendering, I wanted to mention that I am using an AuthStack too, which is returned when the user is logged out:
AuthStack.tsx:
export default function AuthStack() {
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name="Welcome" component={WelcomeScreen} />
<Stack.Screen name="Sign In" component={LoginScreen} />
<Stack.Screen name="Sign Up" component={SignUpScreen} />
<Stack.Screen name="Forgot Password" component={ForgotPasswordScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
index.tsx:
export default function RootNavigation() {
const { user } = useAuth();
return user ? <Tabs /> : <AuthStack />;
}
App.tsx:
export default function App() {
return <RootNavigation />;
}
What am I doing wrong?
I already tried to find a solution in this post but I couldn’t find any answer that solved my problem.
Alright, Your <NavigationContainer>
should be at the root level. Your stack needs to look like this:
App.js/tsx
const App = () => {
return (
<NavigationContainer>
<RootNavigator />
</NavigationContainer>
)
}
RootNavigator.js/tsx
const stack = CreateNativeStackScreenNavigator() // assuming you're using react-native-screens
const RootNavigator = () => {
const { user } = useAuth()
return (
<Stack.Navigator>
{ user ?
<Stack.Screen name={'AuthStack'} component={AuthStack}
: <Stack.Screen name={'Tabs'} component={Tabs} }
<Stack.Screen name={'Second'} component={Second}
</Stack.Navigator>
)
}
Now with this structure, you can navigate to the ‘Second’ screen from any child StackNavigator/TabNavigator/Drawer inside the RootNavigator.
It’s hard to say, as you have not shared which component (or its code) is causing the error, but I would assume that the navigator on which you are calling
navigate
does not have a screen named “Tabs”. E.g. if you are calling this within the tabs component itself, or a screen within the tab navigator.You should include the component that is causing the errors code/routing. It is hard to say what is wrong when we can’t see where the error is being thrown.
I updated my answer, so you can see from which component I am calling the navigate function, where the error is thrown.