How to reset tab stack when you come back to a tab from another tab react navigation v5

Viewed 4683

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"

4 Answers

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.

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

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());
      }
    });
  },
});

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"/>
Related