0

I have a navigation structure set up as below:

  • Tab 1
    • Screen 1 (Initial Page)
    • Screen 2
  • Tab 2
    • Screen 3 (Initial Page)
    • Screen 4

Scenario: There will be cases when Screen 1 has to directly navigate to Screen 4. What I wanted to do is to go back from Screen 4 back to Screen 1, and when I navigate back to Tab 2 by clicking on the tab buttons, it should show me Screen 3.

Steps:

  1. Triggered a navigation from Screen 1 to 4, works totally fine:

    this.props.navigation.navigate("Tab 2", {
      screen: "Screen 4",
      initial: false,
      params: {...some params}
    })
    
  2. Triggered a goBack function on Screen 4, which redirects back to Screen 3, which is fine:

    goBack() {
      this.props.navigation.goBack();
    }
    
  3. Click on Tab 1 and redirect back to Screen 1. Works fine.

  4. Problem occurs: Click on Tab 2, but showing Screen 4, which I want it to be showing Screen 3.

I looked up on other posts saying that one way is to reset the stack actions or something like that but I couldn't a hang of it.

Versions:

"@react-navigation/bottom-tabs": "^6.3.1",
"@react-navigation/drawer": "^6.4.3",
"@react-navigation/native": "^6.0.13",
"@react-navigation/native-stack": "^6.6.2",
"@react-navigation/stack": "^6.2.1",

Update

Found this reference on the internet and got it working. (https://www.reactnativeschool.com/reset-stack-inside-tab-after-leaving-tab)

v6 seems does not support dangerouslyGetState() function, and replaced with getState() instead.

  1. Create a function like below
  TabPressListener = ({ navigation, route }: any) => ({
    tabPress: (e: any) => {
      const state = navigation.getState();
      if (state) {
        // Grab all the tabs that are NOT the one we just pressed
        const nonTargetTabs = state.routes.filter((r: any) => r.key !== e.target);

        nonTargetTabs.forEach((tab: any) => {
          // Grab the key of the nested stack
          const stackKey = tab?.state?.key;

          // Pass the stack key that we want to reset and use popToTop to reset it
          navigation.dispatch({
            ...StackActions.popToTop(),
            target: stackKey,
          });
        });
      }
    }
  })
  1. On the Tab.Screen component, add property "listener" which reference the above function.
<Tab.Screen
   name={'Tab 1'}
   listener={this.TabPressListener}
>
{...}
</Tab.Screen>

<Tab.Screen
   name={'Tab 2'}
   listener={this.TabPressListener}
>
{...}
</Tab.Screen>

Previously I had the flag "unmountOnBlur" set to TRUE. And ever since I commented this line of setting (which then defaults to FALSE) together with triggering the function on Step 1, the stack under each tab is reseting whenever exiting.

Hope this helps for those who got stuck on the same issue.

1 Answer 1

0

To reset the navigation options navigate to Tab 2 with this code:

navigation.reset({index:0, routes: [{name: “Tab 2”}]})
Sign up to request clarification or add additional context in comments.

3 Comments

Do you mean adding a tab press listener inside the Tab.Screen component, and trigger the above reset function?
You want it to reset to the default screen of the Tab 2 navigator every time you click on Tab 2 so call this function when the Tab 2 button is pressed. Using a listen one way to do that.
After drilling down on this direction, got it working as documented on above. Thanks for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.