8

I have 3 tabs and each tab contains a set of stack navigators.

  1. Home Stack
    const HomeNavigator = createStackNavigator();

    const HomeStackNavigator = ({navigation, route}) => {
      return (
        <HomeNavigator.Navigator>
          <HomeNavigator.Screen
            name="Home"
            component={Home}
          />
          <HomeNavigator.Screen
            name="Profile"
            component={Profile}
          />
          <HomeNavigator.Screen
            name="Settings"
            component={Settings}
          />
        </HomeNavigator.Navigator>
      );
    };

  1. Store Stack

    const StoreNavigator = createStackNavigator();

    const StoreStackNavigator = ({navigation, route}) => {
      return (
        <StoreNavigator.Navigator>
          <StoreNavigator.Screen
            name="OurStore"
            component={Store}
          />
        </StoreNavigator.Navigator>
      );
    };

  1. Community Stack
    const CommunityNavigator = createStackNavigator();

    const CommunityStackNavigator = ({navigation, route}) => {
      return (
        <CommunityNavigator.Navigator>
          <CommunityNavigator.Screen
            name="Community"
            component={Community}
          />
          <CommunityNavigator.Screen
            name="CommunityReply"
            component={CommunityReply}
            options={communityReplyOptions}
          />
          <CommunityNavigator.Screen
            name="AskCommunity"
            component={AskCommunity}
          />
        </CommunityNavigator.Navigator>
      );
    };

Tab Navigator


    const MainNavigator = createBottomTabNavigator();

    const MainTabNavigator = () => {
      return (
        <MainNavigator.Navigator
          screenOptions={tabScreenOptions}
          tabBarOptions={tabBarOptions}>
          <MainNavigator.Screen
            name="HomeTab"
            component={HomeStackNavigator}
            options={{tabBarLabel: 'Home'}}
          />
          <MainNavigator.Screen
            name="StoreTab"
            component={StoreStackNavigator}
            options={{tabBarLabel: 'Store'}}
          />
          <MainNavigator.Screen
            name="CommunityTab"
            component={CommunityStackNavigator}
            options={{tabBarLabel: 'Community'}}
          />
        </MainNavigator.Navigator>
      );
    };

I navigated to CommunityReply Screen which is inside CommunityTab tab from HomeTab by clicking a button using the below approach

props.navigation.navigate('CommunityTab', { screen: 'CommunityReply', params: {postId: postId}, });

It's working fine, when I again come back to CommunityTab it will always be in CommunityReply Screen. How to reset tab stacks when you come back to a CommunityTab tab

React Navigation Versions

"@react-navigation/bottom-tabs": "^5.8.0"

"@react-navigation/native": "^5.7.3"

"@react-navigation/stack": "^5.9.0"

Vineel
  • 235
  • 2
  • 4
  • 10

4 Answers4

21

There is a property called unmountOnBlur designed for this purpose.

https://reactnavigation.org/docs/bottom-tab-navigator#unmountonblur

Changes to make in Tab Navigator :

const MainNavigator = createBottomTabNavigator();

const MainTabNavigator = () => {
  return (
    <MainNavigator.Navigator
-     screenOptions={tabScreenOptions}
+     screenOptions={{...tabScreenOptions, unmountOnBlur: true }}
      tabBarOptions={tabBarOptions}>
      <MainNavigator.Screen
        name="HomeTab"
        component={HomeStackNavigator}
        options={{tabBarLabel: 'Home'}}
      />
      <MainNavigator.Screen
        name="StoreTab"
        component={StoreStackNavigator}
        options={{tabBarLabel: 'Store'}}
      />
      <MainNavigator.Screen
        name="CommunityTab"
        component={CommunityStackNavigator}
        options={{tabBarLabel: 'Community'}}
      />
    </MainNavigator.Navigator>
  );
};

Summary:
unmountOnBlur: true will solve the problem mentioned.

stollr
  • 6,534
  • 4
  • 43
  • 59
Etienne Tonnelier
  • 2,119
  • 1
  • 15
  • 14
5

If you don't want the CommunityReply screen to show when you navigate back to the CommunityTab you need to add an initial option within your navigate function.

props.navigation.navigate(
  'CommunityTab', 
  { 
    screen: 'CommunityReply', 
    initial: false, 
    params: { postId: postId }, 
  }
);

Explained here in the docs

Jackson
  • 101
  • 2
  • 3
4

I made a more generic approach to Jeison Guimarães solution (react navigation 6). This approach resets any stack navigation within a tab when the tab index changes. This also makes sure the active stack is not reset when a popover is shown.

<Tab.Screen
  name="My tab"
  listeners={resetTabStacksOnBlur}
/>
/**
 * Resets tabs with stackNavigators to the first route when navigation to another tab
 */
const resetTabStacksOnBlur = ({navigation}) => ({
  blur: () => {
    const state = navigation.getState();

    state.routes.forEach((route, tabIndex) => {
      if (state?.index !== tabIndex && route.state?.index > 0) {
        navigation.dispatch(StackActions.popToTop());
      }
    });
  },
});
Bob
  • 41
  • 1
  • Thank you. This solution is more efficient, it doesn't completely unmount stack therefore maintaining performance between tab changes and gives you more control across tabs. – Plague May 07 '23 at 19:21
1

If the solution above not working for you, try this solution, its work for me.

import { CommonActions } from '@react-navigation/native';

<Tab.Screen listeners={({navigation,route})=>({
    blur:()=>{
      navigation.dispatch(
        CommonActions.reset({
          index:4,
          routes:[{name:'Profile'}]
        })
      )
    },
  })} name="Profile"/>
  • 1
    Where did index:4 come from? Did you hard-code your nav index? – adhdj Dec 05 '20 at 22:23
  • 1
    Tab.Navigator works with a stack that starts from index 0, they are defined by the order you placed, so it’s easy to know which screen index you want, I had 5 tabs and I wanted to get the last one, so I took the from index 4 – Jeison Guimarães Dec 07 '20 at 12:27