28

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);
AHinson
  • 661
  • 2
  • 7
  • 15
  • I can confirm that this does not work in the latest version. – TIMEX Oct 06 '18 at 18:41
  • @TIMEX, please upload a reproduction repository of your issue on Gitlab or Github. I have some experience in `React Native` and `React Navigation`. I can help you. -- reproduction repository: a minimized version of your project that has the issue. – AmerllicA Oct 06 '18 at 20:06
  • How could I navigate to Screen3 but also reset the StackNavigator Tab2? Do you want this to happen when you click on Tab2? – Kranthi Oct 10 '18 at 05:13

8 Answers8

21

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

Sahil Khurana
  • 478
  • 4
  • 10
bitman
  • 469
  • 3
  • 7
  • won't that reset the first tab instead of the tab you're navigating to? – Asaf David Oct 14 '18 at 19:58
  • Perfect Answer. Thanks – Chitra Nandpal Feb 21 '19 at 09:44
  • Thanks, but it works for by resetting the whole tab navigator, like let resetAction = StackActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'tabScreen' }), ] }); this.props.navigation.dispatch(resetAction); this.props.navigation.navigate('Cart') – Sardar Usama Jan 23 '20 at 07:09
  • 1
    This answer is outdated. V5 does not use `actions` anymore, rather `routes`. – Ren Sep 23 '20 at 16:20
3

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.

Pritish Vaidya
  • 21,561
  • 3
  • 58
  • 76
3

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

Olegdater
  • 2,381
  • 22
  • 20
  • This solution is perfect. Here's how I did it in react-navigation V4, const resetAction = StackActions.reset({ index: 0, key: 'xxx', actions: [ NavigationActions.navigate({ routeName: MainTabs, action: NavigationActions.navigate({ routeName: 'Tab2' }) }), ], }); navigation.dispatch(resetAction); – Harshitha Palihawadana Dec 16 '20 at 08:25
1

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);
Kranthi
  • 1,040
  • 8
  • 15
0

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');
AmerllicA
  • 29,059
  • 15
  • 130
  • 154
0

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

Paras Agrawal
  • 21
  • 1
  • 3
0

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.

Clark
  • 21
  • 4
-1

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" />,
    }}
  />
Zohaib Ahmad
  • 310
  • 3
  • 8
  • This effectively unmounts the entire tab, causing it to reload everytime you open it again, which is not what most people (including myself) are after as it introduces a lot of other side effects. – JoniVR Nov 30 '20 at 10:08
  • then you can follow this link. here are some of the navigation events that will help you https://reactnavigation.org/docs/navigation-events/ – Zohaib Ahmad Nov 26 '21 at 12:14