react-nativereact-navigation-bottom-tabexpo-router

How to pop to the top of stack after navigating between tabs with nested stack navigators?


I have a situation where I have some tab screens with nested stack navigators.

Tab1: Home Screen Tab2: Stack Navigator

The initial screen in the Stack Navigator has links to different screens within the stack navigator.

On the Home Screen, I have links to the screens nested in the stack navigator of Tab2 which I can navigate to. I then use the useNavigation hook to goBack to the previous screen which works correctly both when navigating to the nested screens from Tab1 or within Tab2. The problem occurs after I navigate from the nested screen in Tab2 to the home screen in Tab 1 and then navigate back to Tab2 through the bottom tab button which should take me to the initial screen of the stack navigator but takes me back to the same nested screen that I came from initially. This article has a similar issue.

Here is the layout for the Tabs:

      <Tabs
      >
        <Tabs.Screen
          name='home'
        />
        <Tabs.Screen
          name='explore'
        />
      </Tabs>

Here is the code for the Stack Layout for the explore screen which in this case I am calling Tab 2:

    <Stack
  
    >
      <Stack.Screen name='index'  />
      <Stack.Screen
        name='epaper'
        options={{

          headerLeft: () => <Back />,
        }}
      />
      <Stack.Screen
        name='watch'
        options={{

          headerLeft: () => <Back />,
        }}
      />

    </Stack>

Solution

  • So I came up with something that seems like the wrong way to do it but it works! and there is more than likely a better way to do it (You guys will let me know) because I can see that this may not scale well but here it goes

    Basically in the the button on the home page which navigates to the nested page in explore tab (Tab2) I use the expo router Link element and I add a param called previous_screen. Which looks something like this

     <Link
        href={{
          pathname: link as Href<string>,
          params: { previous_screen: 'home' },
        }}
        asChild
      >
    

    Then I have a generic back button which I use throughout the whole application which looks something like this

    export default function Back() {
    const params = useGlobalSearchParams();
     const navigation = useNavigation();
    
     const onPress = () => {
    if (params.previous_screen) {
      navigation.dispatch(StackActions.replace('index'));
      return navigation.navigate(params.previous_screen as never);
    }
    return navigation.goBack();
    };
    
    return (
    <Ionicons
      name='chevron-back'
      size={24}
      color={colorScheme === 'dark' ? 'white' : 'black'}
      onPress={onPress}
    />
    );
    }
    

    When the back button is pressed I check for the previous_screen param and then I replace the current screen which would be the nested page in Tab2 with the initial page you should land on when you click tab2 which is the index page then I navigate to the previous screen.

    Then when I try to go to Tab2 it goes to the index page as expected.