7
votes

My app has a TabNavigator with a StackNavigator in each Tab. I'm not resetting the stacks when navigating between them by clicking on different tabs, so when you change tab, the stack contains the previous state. However, occasionally from within a Screen in one Tab, I want to navigate to a specific Screen in a different tab, and on that occasion, I want to reset the stack in the target Tab.

TabNavigator
    Tab1 
      StackNavigator
         - ScreenA
         - ScreenB
    Tab2
      StackNavigator
         - Screen1
         - Screen2

I want to be able to put a button on Screen2 that resets the Stack on Tab1.

I was wondering if the "target" parameter mentioned in the docs here might help, but there's no examples of how to use it. https://reactnavigation.org/docs/navigation-actions/

(I have searched on here but answers suggested for 4.x don't seem to apply anymore). Thanks!

2
No answer yet hey? Reading that using this reactnavigation.org/docs/navigation-actions/#reset might be on the right track but I can not find a solutionTaylor A. Leach
Same problem here. Did you find a solution?Victor Molina
@VictorMolina I have posted an answer below - it's a while ago now but this is roughly the approach I tookanorakgirl

2 Answers

3
votes

In the end I was able to use the reset action to do this. I dispatched nested state for the tab I wanted to reset:

navigation.dispatch(
  CommonActions.reset({
    routes: [
      {
        name: 'tab-route-name',
        state: {
          routes: [
            { name: 'stack-route-1' },
            { name: 'stack-route-2' },
            { name: 'stack-route-3' }
          ]
        }
      }
    ]
  })
)

It seems to be clever enough that as long as the tab navigator is a parent of the current route, it will find it and reset it.

1
votes

Thank you @anorakgirl. it works perfectly! I want to add some other cases people might want to know. Since the app usually consists of 4-5 tabs.

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.