Navigate multiple screens deep into a stack within a tab navigator

Viewed 833

In my react-navigation app (5.x) , I have this navigation structure:

  • Tabs
    • Home
    • Stack1
    • Stack2
    • Stack3

Tabs is a tab navigator; each StackN is a stack navigator with 3 screens; e.g. Stack1ScreenA, Stack1ScreenB, Stack1ScreenC.

My goal: navigate from Home (the initial screen) to e.g. Stack1 > Stack1ScreenA > Stack1ScreenB > Stack1ScreenC.

I've been attempting to use something like this (similar to this answer), to no avail:

navigation.dispatch(
  CommonActions.reset({
    index: 2,
    routes: [
      {
        name: 'Stack1',
        params: { screen: 'Stack1ScreenA' },
      },
      {
        name: 'Stack1',
        params: { screen: 'Stack1ScreenB' },
      },
      {
        name: 'Stack1',
        params: { screen: 'Stack1ScreenC' },
      },
    ],
  })
)

but I just end up at the default screen of Stack1 (which is Stack1ScreenA).

This is all a bit abstracted from my actual code, of course. My next step is to put together a minimal code example that actually does only the above, but I thought I'd reach out here in the meantime to see if anyone sees an obvious mistake I'm making.

Update: here's a Snack: https://snack.expo.dev/@brettdh/react-navigation-nested-tab-stack-deep-nav

Update update: I fixed the bug in the snack; not yet sure if my app has the same bug or a different one.

Update^3: ok, almost there. I have it working in my app now, except that when I jump three screens into the stack, they open in "modal" mode (sliding up from the bottom on iOS), rather than sliding in from the right as they do when I go one screen at a time. I checked the snack and the behavior there on iOS is the same. Looking into how to get the .reset to behave like the one-by-one screen navigation.

1 Answers

It turns out that the key to everything here is understanding which navigator's state you want to set.

In my case, I wanted to set two navigators' state:

  1. The tab navigator, to the Stack1 tab
  2. The stack navigator in tab Stack, with three screens pushed onto the stack

First complication: as you can see in the Snack linked above, an additional complication not mentioned in my original question was that the tab navigator is itself wrapped in another stack navigator (for displaying modal screens as needed). So, the challenge with the last part (see "Update^3" above) was to make sure I was setting the stack state of the inner stack navigator (which is set to use the default slide-from-the-right animation), not the outer one (which is set to use the "modal" slide-up-from-the-bottom animation).

So, the action I really needed to dispatch was this:

CommonActions.reset({
    routes: [
      {
        name: 'Stack1',
        state: {
          routes: [
            { name: 'Stack1ScreenA' },
            { name: 'Stack1ScreenB' },
            { name: 'Stack1ScreenC' },
          })),
        },
      },
    ],
})

As best as I can tell, the key here is the nesting of the state, so that the dispatched action sets the state of the intended navigator.

Related