8
votes

With react-navigation 4, I was able to import and use switchNavigator from "react-navigation" package.

import {
  createAppContainer,
  createSwitchNavigator,
  createStackNavigator
} from "react-navigation";

import MainTabNavigator from "./MainTabNavigator";
import LoginScreen from "../screens/LoginScreen";
import AuthLoadingScreen from "../screens/AuthLoadingScreen";

export default createAppContainer(
  createSwitchNavigator(
    {
      App: MainTabNavigator,
      Auth: AuthLoadingScreen,
      Login: createStackNavigator({ Login: LoginScreen })
    },

    {
      initialRouteName: "Auth"
    }
  )
);

With react-navigation 5, I don't see the createSwitchNavigator in the package anymore. The documentation isn't helpful either. Is the use now not recommended? My use case is to show login screen before user is logged in and switch to the app after user logs in. React-navigation has given an example of authentication flow but is it possible to use switchNavigator - which seems much simpler.

4

4 Answers

18
votes

The switchNavigator was removed because you can do the exact same stuff now with the help of rendering components conditionally.

import React from 'react';
import {useSelector} from "react-redux";
import {NavigationContainer} from "@react-navigation/native";

import { AuthNavigator, MyCustomNavigator } from "./MyCustomNavigator";

const AppNavigator = props => {
    const isAuth = useSelector(state => !!state.auth.access_token);

    return (
        <NavigationContainer>
            { isAuth && <MyCustomNavigator/>}
            { !isAuth && <AuthNavigator/>}
        </NavigationContainer>
    );
};
export default AppNavigator;

The lines inside the NavigationContainer fully replace the old switch navigator.

5
votes

I had also used SwitchNavigator of Navigator 4 then after migrating other pages to Navigator 5, i tried to move authentication part to Navigator 5. I could not achieve SwitchNavigator functionality using Navigator 5. Then decided to use "Compatibility layer" provided in Navigation API 5. https://reactnavigation.org/docs/compatibility/
Hope below code will useful for you.

import { createStackNavigator } from '@react-navigation/stack'
import { NavigationContainer } from '@react-navigation/native';
import { createSwitchNavigator } from "@react-navigation/compat";
import { createCompatNavigatorFactory } from '@react-navigation/compat'
 const AppStack = createCompatNavigatorFactory(createStackNavigator)(
      { screen: Home },
      {headerMode:'none'}
 );
 const AuthStack = createCompatNavigatorFactory(createStackNavigator)({ screen:Login });
const SwitchNavigator= createSwitchNavigator(
      {
    Starter: AuthValidation,
    App: AppStack,
    Auth: AuthStack
  },
  {
    initialRouteName:'Starter'
  }
);
export default function App (){
  
    return(
      <NavigationContainer>
          <SwitchNavigator/>
      </NavigationContainer>
    );
}

_checkAuthetication = async() =>{
  const isUserAuthenticated= await AsyncStorage.getItem("isAuthenticated");
  this.props.navigation.navigate(isUserAuthenticated ? 'App':'Auth');
}
2
votes

Hey there is no switch navigator in react navigation 5, however you can do this or something on the same lines:

import React, { useEffect } from 'react'
import { StyleSheet, Text, View, ActivityIndicator } from 'react-native'
import { NavigationContainer } from "@react-navigation/native";
import BottomTabsNavigator from './BottomTabsNavigator'
import AccountNavigator from './AccountNavigator'
import firebase from '../api/config'


const SwitchNavigator = ({navigation}) => {
    useEffect(() => {
        firebase.auth().onAuthStateChanged(user => {
            navigation.navigate(user ? "BottomTabsNavigator" : "AccountNavigator")
        })
      }, [])



    return (
        <View style={styles.container}>
            <Text>Loading...</Text>
            <ActivityIndicator size="large" color="#e9446a"></ActivityIndicator>
        </View>
    )
}


const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
})

export default SwitchNavigator

and then a Stack Navigator :

import React from 'react'
import { createStackNavigator } from '@react-navigation/stack'
import BottomTabsNavigator from './BottomTabsNavigator'
import AccountNavigator from './AccountNavigator'
import SwitchNavigator from './SwitchNavigator'
import { NavigationContainer } from "@react-navigation/native";

const StackApp = createStackNavigator()

export default function Stack() {
   return (
      <NavigationContainer>
      <StackApp.Navigator initialRouteName='Loading' headerMode='none'>
        <StackApp.Screen name='Loading' component={SwitchNavigator} />
        <StackApp.Screen name='AccountNavigator' component={AccountNavigator}/>
        <StackApp.Screen name='BottomTabsNavigator' component={BottomTabsNavigator}/>
      </StackApp.Navigator>
     </NavigationContainer>

)
}

and then import the Stack navigator into your app.js file like this:

export default App = () => ( <Stack /> )
0
votes

This is w.r.t to above query

[Then how could we later navigate from a "LoginScreen" (inside
AuthNavigator ) to "HomeScreen" (inside MyCustomNavigator )? – TalESid
Apr 7 at 8:33 ]
const AuthNavigator = () => {
  return(
  <AuthStack.Navigator>
  <Stack.Screen
    name="Login"
    component={Login}
    options={{ headerShown: false }}
  />
  <Stack.Screen
    name="SignUp"
    component={SignUp}
    options={{ headerShown: false }}
  />
  </AuthStack.Navigator>
);
  }
const MyCustomNavigator = () => {
  return(
  <AppStack.Navigator>
  <Stack.Screen
    name="Home"
    component={Home}
    options={{ headerShown: false }}
  />
  <Stack.Screen
    name="ListScreen"
    component={ListScreen}
    options={{ headerShown: false }}
  />
  <Stack.Screen
    name="Settings"
    component={Settings}
    options={{ headerShown: false }}
  />
  </AppStack.Navigator>
  );
}

const AppNavigator = (props) => {
const isAuth = useSelector((state) => !!state.auth.access_token);

return (
  <NavigationContainer>
    {isAuth && <MyCustomNavigator />}
    {!isAuth && <AuthNavigator />}
  </NavigationContainer>
);
};
export default AppNavigator;