skip to Main Content

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.

2

Answers


  1. 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.

    Login or Signup to reply.
  2. I believe the issue is that you have 2 NavigationContainers.

    You only need one NavigationContainer in the root of your app as it "is responsible for managing your app state and linking your top-level navigator to the app environment" – https://reactnavigation.org/docs/navigation-container/

    I believe having a second NavigationContainer within your tabs component is the root of the problem as this is preventing access to the navigation above that level.

    Update your Tabs.tsx to the following and the error should go away:

    <Tab.Navigator>
      // other screens here
      <Tab.Screen
        name="First"
        component={First}
      />       
    </Tab.Navigator>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search