clear stack when navigating to nested stack navigator inside bottom tab navigator

Viewed 212

Current Behavior

My react-native application consists of a BottomTabNavigator that contains several StackNavigators. A simplified example of my structure looks like this

userLoggedIn or signinSkiped ? (

BottomTab

  • Tab 1
    • Stack

      • Screen 1

      • Screen 2

  • Tab 2
    • Stack

      • Screen 1

      • Screen 2

) : ( Stack

  • SigninScreen

  • RegisterScreen

)

**My problem is: **

  1. I log in into my application
  2. I am on Screen 1 of the Tab 1.
  3. From the Screen 1 of the Tab 1 i navigate to Screen 2 of the Tab 1 on the press button.
  4. From the Screen 2 of the Tab 1 i navigate to Screen 2 of the Tab 2 on the press button.
  5. I log out from my application
  6. I am on SigninScreen
  7. I click on the button "signinSkip" on the SigninScreen (signinSkiped = true)
  8. I am on the Screen 1 of the Tab 1
  9. I click on Tab 2
  10. Screen 2 of the Tab 2 is displayed

**Expected behavior: **

When I click on Tab 2 as described in the step 9 above, Screen 1 of the Tab 2 should be displayed and not the Screen 2.

It works as expected, if I do following steps:

  1. I sign in into my application
  2. I am on the Screen 1 of the Tab 1
  3. I click on Tab 2 and I'm on the Screen 1 of the Tab 2
  4. From the Screen 1 of the Tab 2 i navigate to Screen 2 of the Tab 2 on the press button.
  5. I log out from my application
  6. I am on SigninScreen
  7. I click on the button "signinSkip" on the SigninScreen (signinSkiped = true)
  8. I am on the Screen 1 of the Tab 1
  9. I click on Tab 2
  10. Screen 1 of the Tab 2 is displayed

I assume, it has to do with refreshing of stack after logging out, but I'm not sure. i would really appreciate your help

I tried following:

Navigate from Screen 2 to Screen 1 of the Tab 2 if the user loggs out (within the onAuthStateChanged listener). I get the expected result, but it leads to the error: Can't perform a React state update on an unmounted component

1 Answers

you can reset your navigation stack when the user logs out of your application. Doing this will keep the behavior consistent.

navigation.dispatch(
        CommonActions.reset({
          index: 0,
          routes: [
            {
              name: 'SigninScreen',                  
            }
          ],
        })
      );

To answer your question on why the SigninScreen. You have nested navigators, which means that whatever you are doing in the parent navigator (tab navigator) is not going to affect the child navigator (screen 1 and 2). The reason why you are seeing the behavior described is that the mounted screens don't get unmounted. Whatever you had in your child navigator won't be reset when the user navigate away from it (i.e. clicking Tab 1 or tab 3 etc.)

The code above will reset all of that when the user gets to the login screen. This will remove all the mounted screens, which will make sure when the user click on Tab 2, screen 1 always gets mounted first.

Alternately, you can add a tab press listener to manually goto Screen 1 when the user press Tab 2.

<Tab.Screen name="Tab 2" component={Tab2}
      listeners={({ navigation }) => ({
        tabPress: (event) => {
          e.preventDefault();
          navigation.navigate(“Tab2”, {screen: “Screen1” };
        }
      })}
    />
Related