React Navigation - navigating to another tab and reset stack

Viewed 11523

I'm trying to route from one StackNavigator to another, both of which are inside a TabNavigator. I'm currently able to get there by simply doing:

this.props.navigation.navigate('Screen3')

But I also want to reset that tab when I go to it. Here is how my app navigators are generally set up:

- Main (StackNavigator)
  - LoginScreen
  - MainTabs (TabNavigator)
    - Tab1 (StackNavigator)
      - Screen1
      - Screen2
    - Tab2 (StackNavigator)
      - Screen3
      - Screen4

How could I navigate to Screen3 but also reset the StackNavigator Tab2?

I've also tried doing this, to no avail:

let resetAction = NavigationActions.reset({
  index: 0,
  key: 'Tab2',
  actions: [
    NavigationActions.navigate({ routeName: 'Screen3' })
  ],
});

this.props.navigation.dispatch(resetAction);
8 Answers

You'll have to dispatch two navigation actions, one to reset the stack of the current tab and another to navigate to the next screen:

let resetAction = StackActions.reset({
  index: 0,
  actions: [
    NavigationActions.navigate({ routeName: 'Screen1' })
  ],
});

this.props.navigation.dispatch(resetAction);
this.props.navigation.navigate('Screen3');

Here is a snack

You can use the advanced action of the navigate api combined with the Navigator dependant functions without using any additional action or navigation call.

Here is an example

navigateWithReset = (routeName) => {
    const navigateAction = NavigationActions.navigate({
      routeName,
      action: this.props.navigation.popToTop(),
    });
    this.props.navigation.dispatch(navigateAction);
  };

The working snack link can be found here.

Here's how I solved this using NavigationService:

NavigationService.reset({
  index: 0,
  key: null, // required to reset tabs
  actions: [
    NavigationActions.navigate({
      routeName: 'MainTabs',
      action: NavigationActions.navigate({ routeName: 'Tab2' }),
    }),
  ],
});
NavigationService.navigate({
  key: 'Screen3',
  routeName: 'Screen3',
});

pay attention to the 'key: null' option, this made it work

First you will have to navigate to the Tab and then reset to the screen you want

this.props.navigation.navigate('Tab2');
let resetAction = StackActions.reset({
  index: 0,
  actions: [
    NavigationActions.navigate(
      {
        routeName: 'Screen3',
        params: {},
        key: Math.random() + 'Screen3'
      }
    )
  ]
})
this.props.navigation.dispatch(resetAction);

It is based on your stack architecture, however, you should navigate after your resetAction dispatching.

After resetAction dispatching use below code:

this.props.navigation.navigate('Screen3');

I was facing the same problem, here is the code that worked for me:-

    let resetAction = StackActions.reset({
      index: 0,
      actions: [
        NavigationActions.navigate({ routeName: 'Screen1' })
      ],
    });

    this.props.navigation.dispatch(resetAction);   // <---- 1
    this.props.navigation.navigate('Tab2');   // <---- 2 
    (IMPORTANT: Here in Line marked as 2, I have used tab name not screen name)

Firstly, I am resetting the current tab and pushing the initial route so that when I come back to this tab, it should land me to the given initial route [Line No. marked as 1]. Then, I am navigating to another tab which lands me to its initial route [Line No. marked as 2].

Here is the solution with React Navigation 5.x

https://stackoverflow.com/a/66982007/10672805



The code below is for resetting multiple tabs.

TabNavigator
    Tab1: 'tab1_name' 
      StackNavigator
         - ScreenA
         - ScreenB

    Tab2: 'tabs_name'
      StackNavigator
         - ScreenC
         - ScreenD

    Tab3: 'tab3_name'
      StackNavigator
         - ScreenE
         - ScreenF
navigation.dispatch(
  CommonActions.reset({
    routes: [
      {
        name: 'tab1_name',
        state: {
          routes: [
            { name: 'ScreenA' },
            { name: 'ScreenB' },
          ]
        }
      },
      {
        name: 'tab2_name',
        state: {
          routes: [
            { name: 'ScreenC' },
          ]
        }
      },
      {
        name: 'tab3_name',
        state: {
          routes: [
            { name: 'ScreenE' },
            { name: 'ScreenF' },
          ]
        }
      },
    ]
  })
)

And with this code, the first page you see is tab1_name tab's ScreenB screen.

So, if you want to see tab3_name tab's ScreenF screen first after running the dispatch function, the code should be something like:

navigation.dispatch(
  CommonActions.reset({
    routes: [
      {
        name: 'tab3_name',
        state: {
          routes: [
            { name: 'ScreenE' },
            { name: 'ScreenF' },
          ]
        }
      },
      {
        name: 'tab1_name',
        state: {
          routes: [
            { name: 'ScreenA' },
            { name: 'ScreenB' },
          ]
        }
      },
      {
        name: 'tab2_name',
        state: {
          routes: [
            { name: 'ScreenC' },
          ]
        }
      },
    ]
  })
)

By the way, when you write down the routes of tab's state, it should follow the sequence of page stack. So that it would work as you expected.

navigation.dispatch(
  CommonActions.reset({
    routes: [
      {
        name: 'tab3_name',
        state: {
          routes: [
            // { name: 'ScreenE' },   // removed
            { name: 'ScreenF' },
          ]
        }
      },
      ...

If you omit the first stack page as above, ScreenE is not accessible but only ScreenF after running the dispatch function.

Hope this works for you.

if you are wroking on tabs and then want to reset the tab then try this React Navigation 5 here is the link here is documentation

 <BottomTab.Screen
    name="Post"
    component={PostStack}
    options={{
      unmountOnBlur: true,// set this props in your tab screen options
      title: 'Post',
      tabBarIcon: focused => <TabBarIcon focused={focused} name="Post" />,
    }}
  />
Related