0
votes

I'm finding difficulty in digesting the official documentation and I'm stuck finding out a solution to move between different stack navigators. I have provided my current implementation and code snippet to explain my problem better.

I have a bottom tab navigator and 2 stack navigators to handle different use cases.

BottomNavigation.js
StackNavigation.js
AuthStackNavigation.js

I have created multiple stack navigators within StackNavigation.js and rendering each StackNavigators within BottomNavigation.js

***StackNavigation.js***

const Stack = createStackNavigator();

const HomeStackNavigator = () => {
    return (
        <Stack.Navigator initialRouteName="Home" screenOptions={ScreenLogo}>
            <Stack.Screen name="HomeScreen" component={Home} />
        </Stack.Navigator>
    );
}

const ProfileStackNavigator = () => {
    return (
        <Stack.Navigator initialRouteName="Home" screenOptions={ScreenLogo}>
            <Stack.Screen name="MahaExpo" component={Profile} />
        </Stack.Navigator>
    );
}

export { HomeStackNavigator, ProfileStackNavigator };

And as I said I'm rendering each navigator inside tab navigator to switch between screens.

 ***BottomNavigation.js***

import { HomeStackNavigator, ProfileStackNavigator } from '../Navigations/StackNavigation'

const Tab = createMaterialBottomTabNavigator();

function BottomNavigation() {
    return (
        <Tab.Navigator
            initialRouteName="Home" >
            <Tab.Screen
                name="Home"
                component={HomeStackNavigator}
            />
            <Tab.Screen
                name="ProfileStackNavigator"
                component={ProfileStackNavigator}
            />
        </Tab.Navigator>
    )
}

export default BottomNavigation

and I'm rendering this within app.js and inside NavigationContainer. I have created AuthStackNavigation.js which has a login and register screens.

***AuthStackNavigation.js***

const AuthStack = createStackNavigator();

const AuthStackNavigation = ({ }) => (

    <AuthStack.Navigator headerMode='none'>
        <AuthStack.Screen name="UserLogin" component={UserLogin}></AuthStack.Screen>
        <AuthStack.Screen name="UserRegister" component={UserRegister}></AuthStack.Screen>
    </AuthStack.Navigator>
);

export default AuthStackNavigation

So currently, I'm showing the home screen with some public content and user can switch to different screens using the bottom tab navigator linked to different screens. When the user clicks on profile tab, im displaying a button to login which should take the user to AuthStackNavigation.js which has a login and register screen. Thanks in advance!

2

2 Answers

1
votes
const ProfileStackNavigator = () => {
    return (
        <Stack.Navigator initialRouteName="Home" screenOptions={ScreenLogo}>
            <Stack.Screen name="MahaExpo" component={Profile} />
            <Stack.Screen name="UserLogin" component={UserLogin} />
            <Stack.Screen name="UserRegister" component={UserRegister} />
        </Stack.Navigator>
    );
}

on profile page check user is logged in or not, if not, simply navigate to UserLogin screen. Once login simply pop back to profile page are refresh.

1
votes

There's no way of communicating between two separate navigators if they're not related to each other (one is a child navigator of another or etc.), unless you create something like RootStackNavigator, which would be on the higher level and which would contain all the navigators you have listed above. Create guest navigators array, authorized navigators array and some shared routes (if needed). Guest navigator contains authstack only and authorized one contains other navigators, if you use redux, context or something like this you can check for the token on startup to determine which navigator you have to use. Logging in will give you the token and will automatically change your navigator to authorized navigators and logging out will throw you back (as you no longer have the token) to the guest navigators which will contain only authentication flow.

Pretty hard to explain ;) hope this helps..

Redux Example

`
const authNavigators = [
{
type: "screen",
key: "authNavigators",
name: "authNavigators",
component: authNavigators,
},
];

const otherNavigators = [
{
type: "screen",
key: "otherNavigators1",
name: "otherNavigator1",
component: otherNavigators1,
},
{
type: "screen",
key: "otherNavigators2",
name: "otherNavigator2",
component: otherNavigators3,
},
...
];

const RootStack = () => {

  const { condition } = useSelector(
  (state) => state.store);

 let navigators = otherNavigators;

 if(condition) {
  navigators = authNavigators;
  }

 return (
 <RootStackNavigator.Navigator>
  {navigators.map((item) => {
    return (
      <RootStackNavigator.Screen
        {...item}
        options={({ route: { params } }) => ({
          ...item.options,
        })}
      />
    );
  })}
</RootStackNavigator.Navigator>
 );
};

export default RootStack;`

from redux, you can dispatch an action which would change that condition and this would dynamically update your navigator.