switchNavigator with react-navigation 5 - react-native

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.

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.

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/5.x/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>
);
}
Here AuthValidation validate for token and depending on value it navigate to "Login" or "Home" Page
_checkAuthetication = async() =>{
const isUserAuthenticated= await AsyncStorage.getItem("isAuthenticated");
this.props.navigation.navigate(isUserAuthenticated ? 'App':'Auth');
}

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 /> )

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;

There isnt a switch navigator in react-navigation v5 or v6. however, i found switch very easy, and i find stack very difficult to use, so i continue to use react-navigation v4.2.0 or 4.4.1, so i can continue using switch

Related

React native navigation not initialized yet

I'm learning react native but I'm having difficulty with navigation, it's returning the error that navigation has not been initialized yet.
I looked for some tutorials, I tried some other ways, I went to the react native navigation documentation and, incredible as it may seem, it's the same as in the documentation... not even the GPT chat haha ​​it didn't help me.
Can someone with experience in react native give me a light?
app.tsx:
import { NavigationContainer } from '#react-navigation/native';
import { createAppContainer } from 'react-navigation';
import StackNavigator from './app/index/navigator';
const AppContainer = createAppContainer(StackNavigator);
const App = () => {
return (
<NavigationContainer>
<AppContainer />
</NavigationContainer>
);
}
export default App;
navigator.tsx?
import { createStackNavigator } from 'react-navigation-stack';
import Index from '.';
import AddNewGrocery from '../components/addNewGrocery'
const StackNavigator = createStackNavigator({
home: { screen: Index, navigationOptions: { headerShown: false } },
addNewGrocery: { screen: AddNewGrocery, navigationOptions: { headerShown: false } },
});
export default StackNavigator;
index.tsx:
const Index = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>Gestão de Compras</Text>
<LastFiveGrocery />
<MonthAverageSpend />
<TotalSpend />
<AddButton />
<StatusBar
translucent={false}
backgroundColor={'rgba(43, 43, 43, 1)'}
barStyle='light-content' />
</View>
);
}
AddButton.tsx:
import React from 'react';
import { StyleSheet, View, TouchableOpacity } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
import { useNavigation } from '#react-navigation/native';
const AddButton = () => {
const navigation = useNavigation();
const handleAddButtonPress = () => {
navigation.navigate('addNewGrocery' as never);
}
return (
<TouchableOpacity style={styles.addButtonContainer} onPress={handleAddButtonPress}>
<View style={styles.addButton}>
<Ionicons name="ios-add" size={36} color="white" />
</View>
</TouchableOpacity>
);
}
I already tried to use it this way:
AddButton:
const { navigate } = useNavigation<StackNavigationProp<ParamListBase>>();
const handleAddButtonPress = () => {
navigate('addNewGrocery');
}
I've also tried using it this way:
navigator:
const StackNavigator = createAppContainer(createStackNavigator({
Home: { screen: Index },
addNewGrocery: AddNewGrocery,
}));
app.tsx:
import StackNavigator from './app/index/navigator';
const App = () => {
return (
<StackNavigator />
);
}
export default App;
You are using 2 different navigation library in simultaneously:
#react-navigation
react-navigation
Remove react-navigation and refactor the App.js file as below:
import { NavigationContainer } from '#react-navigation/native';
import StackNavigator from './app/index/navigator';
const App = () => {
return (
<NavigationContainer>
<StackNavigator />
</NavigationContainer>
);
}
export default App
StackNavigator should be implemented as per documentation -
https://reactnavigation.org/docs/stack-navigator/#api-definition

How to hide the drawer header from stack's child component?

I would like to hide drawer navigation from the list component and it still be shown in the UserHomeScreen which is the stack navigation. It works if I just use the useState, hideHeader/setHideHeader, from App.js but it is not efficient way to do this. I tried my best to look for a solution but I really can't find. I am new to react native and have a limited knowledge.
Can anyone help me how am I going do it? Please help.
BTW here is the version of my drawer: ^6.0.1, if that helps.
Thank you so much!
App.js
import React from 'react'
// components
import UserHomeScreen from './src/components/user/pages/UserHomeScreen';
import Cart from './src/components/user/pages/Cart';
import Receipt from './src/components/user/pages/Receipt';
//redux
import store from './src/redux/store'
// libraries
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { Provider } from 'react-redux';
const Drawer = createDrawerNavigator();
const App = () => {
const [hideHeader, setHideHeader] = React.useState(false);
return (
<Provider store={store}>
<NavigationContainer>
{/* this hide drawer */}
{/* options={{headerShown: false}} */}
<Drawer.Navigator >
<Drawer.Screen name="Home" >
{() => <UserHomeScreen setHideHeader={setHideHeader} />}
</Drawer.Screen>
<Drawer.Screen name="Cart" component={Cart} />
<Drawer.Screen name="Receipt" component={Receipt} />
</Drawer.Navigator>
</NavigationContainer>
</Provider>
)
}
export default App;
UserHomeScreen.js
import React from 'react'
import List from '../components/User Home Screen/List';
import { createStackNavigator } from '#react-navigation/stack';
import ItemDetails from '../components/User Home Screen/ItemDetails';
import { useNavigation } from '#react-navigation/native';
import { Button } from 'react-native';
const Stack = createStackNavigator();
const UserHomeScreen = () => {
function backHandler(){
navigation.navigate('List')
}
// this hide the drawer header but I want it inside the list
// but if I do, the stack header that hides not the drawer header.
// React.useEffect(() => {
// navigation.setOptions({
// headerShown: false
// });
// })
const navigation = useNavigation();
return (
<Stack.Navigator>
<Stack.Screen name='List' component={List}>
</Stack.Screen>
<Stack.Screen name='Item Details' component={ItemDetails}
options={{
headerLeft: () => <Button title='Back' onPress={backHandler}/>
}}
/>
</Stack.Navigator>
)
}
export default UserHomeScreen;

How does this V4 Navigation look like now it's V6?

I would like to convert the following react-navigation code (v4) to v6. What will the following now look like? This is in each of my screens.
import { withNavigation } from "react-navigation";
import { TransitionPresets } from 'react-navigation-stack';
const styles = StyleSheet.create({
...
)}
OtpScreen.navigationOptions = () => {
return {
header: () => null,
...TransitionPresets.SlideFromRightIOS,
}
}
export default withNavigation(MyScreen);
According to the doc, you can add your options directly inside the navigator definition.
After install the npm packages, for a stack navigator try this:
import { createStackNavigator } from '#react-navigation/stack';
import { TransitionPresets } from '#react-navigation/stack';
...
const Stack = createStackNavigator();
export default function MyStack() {
return (
<Stack.Navigator screenOptions ={... // your global options here}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen
name="Profile"
component={Profile}
options={{
...TransitionPresets. SlideFromRightIOS,
... // others specific options
}}
/>;
</Stack.Navigator>
);
}
Then in your App.js
import { NavigationContainer } from '#react-navigation/native';
import MyStack from ../path/to/file
... // others imports
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
)
}
WithNavigation has been removed since v5.
Here is the link to the doc

React Native React Navigation screen does not redirect after login with AsyncStorage

So I built a login system with React Native, React Navigation and AsyncStorage. If the user clicks on a button he gets logged in and the value of the AsyncStorage Key "#loginuser" gets refreshed. Now I expected
that the screen automatically gets refreshed, but I have to close the App and start it again - This is not optimal.
(I also saw React-Native/React navigation redirection after login with redux post, but it is very old)
App.js
import React from 'react';
import { Text, View, StyleSheet, Button, TouchableOpacity, TextInput } from 'react-native';
import DefaultStackNavigation from './components/Navigation/Navigation';
const App = () => {
return(
<View>
<DefaultStackNavigation />
</View>
)
}
export default App;
Navigation.js
import React, {useEffect, useState} from 'react';
//React Native
import { Text, View, StyleSheet} from 'react-native';
//Screens
import HomeScreen from '../HomeScreen/HomeScreen'
import AddScreen from "../AddScreen/AddScreen";
import NotificationScreen from "../NotificationScreen/NotificationScreen";
import MenuScreen from "../MenuScreen/MenuScreen";
import SearchScreen from "../SearchScreen/SearchScreen";
import PostJobScreen from "../PostJobScreen/PostJobScreen";
import JobOfferScreen from "../JobOfferScreen/JobOfferScreen";
import ProfileScreen from "../ProfileScreen/ProfileScreen";
import NoneLoggedinScreen from "../NoneLoggedinScreen/NoneLoggedinScreen"
import SignupModal from "../NoneLoggedinScreen/SignupModal"
//React Navigation
import { createStackNavigator } from "#react-navigation/stack";
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
//Third Party
import AsyncStorage from '#react-native-async-storage/async-storage';
const Tab = createBottomTabNavigator();
//Tab bar
const HomeTabs = () => {
return (
<Tab.Navigator tabBarOptions={{style:{height: 50}}, {showIcon: true}, {showLabel: false}} >
<Tab.Screen name="Home" component={HomeScreen}/>
<Tab.Screen name="SearchScreen" component={SearchJobStack}/>
<Tab.Screen name="AddScreen" component={AddScreen}/>
<Tab.Screen name="NotificationScreen" component={NotificationScreen} />}}/>
<Tab.Screen name="MenuScreen" component={MenuScreen}/>}}/>
</Tab.Navigator>
);
}
const Stack = createStackNavigator();
const STORAGE_KEY = '#loginStatus'
const DefaultStackNavigation = () => {
const [loginStatus, setLoginStatus] = useState()
const readData = async () => {
try {
const isLoggedIn = JSON.parse(await AsyncStorage.getItem(STORAGE_KEY))
console.log(isLoggedIn)
if (isLoggedIn !== null) {
setLoginStatus(isLoggedIn)
}
} catch (e) {
alert('Failed to fetch the data from storage')
}
}
readData()
return loginStatus ? (
<NavigationContainer>
<Stack.Navigator screenOptions={{headerShown: false}} independent={false}>
<Stack.Screen name="HomeTabs" component={HomeTabs} />
<Stack.Screen name="PostJobScreen" component={PostJobScreen} />
<Stack.Screen name="ProfileScreen" component={ProfileScreen}/>
</Stack.Navigator>
</NavigationContainer>
) : (
<NavigationContainer>
<Stack.Navigator screenOptions={{headerShown: false}} independent={false}>
<Stack.Screen name="NoneLoggedinScreen" component={NoneLoggedinScreen} />
<Stack.Screen name="SignupModal" component={SignupModal} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default DefaultStackNavigation;
NoneLoggedinScreen.js
import React, { useState, useEffect } from 'react';
import { Text, View, Button} from 'react-native';
import AsyncStorage from '#react-native-async-storage/async-storage';
const STORAGE_KEY = '#loginStatus'
const SignupModal = () => {
const [loginStatus, setLoginStatus] = useState(false)
const saveData = async (parmLoginStatus) => {
try {
await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(parmLoginStatus))
alert('Data successfully saved -> Logged In')
console.log(loginStatus)
} catch (e) {
alert('Failed to save the data to the storage')
}
}
const onSubmitLogin = () => {
setLoginStatus(true)
saveData(true)
}
return(
<View>
<Text>Login Page. Press the button to log in and stay logged in</Text>
<Button title="Log in" onPress={() => onSubmitLogin()}/>
</View>
);
};
const styles = StyleSheet.create({
App: {
flex: 1,
backgroundColor: "white"
},
});
export default SignupModal;
Now I was expecting the page to reload and I can use the app. Unfortunately it doesn't. The data is saved and the login status is set to true, but I have to restart the app to use it. The perfidious thing is, if I write the AsyncStorage login logic from the NoneLoggedinScreen.js file into the App.js file, the app works fine -> However, this is not an alternative for me, because the general structure of the app is, I think, built relatively sensibly.
Also when the user tries to be redirected manually (by button) with navigation.navigate("HomeTabs") after logging in doesn't work, and I get an error that Home doesn't exist, which is also not understandable, because the navigation has actually been set to Logged in now. Has anyone ever had this problem?
This are my dependencies by the way
"dependencies": {<br>
"#react-native-async-storage/async-storage": "^1.15.1",<br>
"#react-native-community/masked-view": "^0.1.10",<br>
"#react-navigation/bottom-tabs": "^5.11.7",<br>
"#react-navigation/native": "^5.9.2",<br>
"#react-navigation/stack": "^5.14.2",<br>
"react": "16.13.1",<br>
"react-native": "0.63.4",<br>
"react-native-gesture-handler": "^1.10.1",<br>
"react-native-reanimated": "^1.13.2",<br>
"react-native-safe-area-context": "^3.1.9",<br>
"react-native-screens": "^2.17.1",<br>
}
In your authentication strategy, there is a hidden assumption that when you save data using AsyncStorage in NoneLoggedInScreen, the data will immediately be read using the readData function in DefaultStackNavigation. The reason why this does not happen is that readData is only called when DefaultStackNavigation renders/re-renders. This will not happen when one of its children sets some data in local storage.
There are many ways to fix this. Using redux with redux-persist or another state-management and persistence setup, or a purpose-built context-based solution (see eg. this Kent C. Dodds article on Authentication in React Applications).
The second, minor issue that you mention:
navigation.navigate("HomeTabs") after logging in doesn't work, and I get an error that Home doesn't exist
does make sense, and the reason behind it is that you conditionally render two different NavigationContainers. They don't know about each others routes, so you can't navigate between them.
To fix this, you should render one NavigationContainer and conditionally render one of the Stack.Navigators as its child.
To manage authentication flow in a smooth way we should make two seperate navigators for the navigation. I find this workflow the best as of now. It works perfectly and is clean.
So what I usually do in my Projects that I create two navigators AuthNavigator.js and AppNavigator.js and then use conditional rendering.
So what you can do is create a folder called navigation where your App.js is located. Then inside navigation folder create two files called AppNavigator.js and AuthNavigator.js.
Your AuthNavigator.js should look like this
import React from "react";
import NoneLoggedinScreen from "../NoneLoggedinScreen/NoneLoggedinScreen";
import SignupModal from "../NoneLoggedinScreen/SignupModal";
import { createStackNavigator } from "#react-navigation/stack";
const Stack = createStackNavigator();
const AuthNavigator = () => {
return (
<Stack.Navigator screenOptions={{ headerShown: false }} independent={false}>
<Stack.Screen name="NoneLoggedinScreen" component={NoneLoggedinScreen} />
<Stack.Screen name="SignupModal" component={SignupModal} />
</Stack.Navigator>
);
};
export default AuthNavigator;
Your AppNavigator.js should look like this
import React from "react";
import HomeScreen from "../HomeScreen/HomeScreen";
import AddScreen from "../AddScreen/AddScreen";
import NotificationScreen from "../NotificationScreen/NotificationScreen";
import MenuScreen from "../MenuScreen/MenuScreen";
import PostJobScreen from "../PostJobScreen/PostJobScreen";
import ProfileScreen from "../ProfileScreen/ProfileScreen";
import { createStackNavigator } from "#react-navigation/stack";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
const Tab = createBottomTabNavigator();
//Tab bar
const HomeTabs = () => {
return (
<Tab.Navigator
tabBarOptions={
({ style: { height: 50 } }, { showIcon: true }, { showLabel: false })
}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="SearchScreen" component={SearchJobStack} />
<Tab.Screen name="AddScreen" component={AddScreen} />
<Tab.Screen name="NotificationScreen" component={NotificationScreen} />
<Tab.Screen name="MenuScreen" component={MenuScreen} />
</Tab.Navigator>
);
};
const Stack = createStackNavigator();
const AppNavigator = () => {
return (
<Stack.Navigator screenOptions={{ headerShown: false }} independent={false}>
<Stack.Screen name="HomeTabs" component={HomeTabs} />
<Stack.Screen name="PostJobScreen" component={PostJobScreen} />
<Stack.Screen name="ProfileScreen" component={ProfileScreen} />
</Stack.Navigator>
);
};
export default AppNavigator;
And your App.js should look like this
import React, { useState, useEffect } from 'react';
import { NavigationContainer } from '#react-navigation/native';
import AuthStorage from './auth/storage';
import AppNavigator from './navigation/AppNavigator';
import AuthNavigator from './navigation/AuthNavigator';
const App = () => {
const [loginStatus, setLoginStatus] = useState(false);
// I am using useEffect hook but I would prefer using `AppLoading` to restore token if it exists
useEffect(() => {
readData();
}, []);
const readData = async () => {
try {
const isLoggedIn = JSON.parse(await AuthStorage.getItem());
console.log(isLoggedIn);
if (isLoggedIn !== null) {
setLoginStatus(isLoggedIn);
}
} catch (e) {
alert('Failed to fetch the data from storage');
}
};
return (
<NavigationContainer>
{loginStatus ? <AppNavigator /> : <AuthNavigator />}
</NavigationContainer>
);
};
export default App;
Create a folder called auth where your App.js is located. Inside that create a file called storage.js. Now inside storage.js paste this code
import AsyncStorage from '#react-native-async-storage/async-storage';
const AuthToken = '#loginStatus';
const storeItem = async (value) => {
try {
await AsyncStorage.setItem(AuthToken, JSON.stringify(value));
return true;
} catch (e) {
return false;
}
};
const getItem = async () => {
try {
const jsonValue = await AsyncStorage.getItem(AuthToken);
return jsonValue != null ? JSON.parse(jsonValue) : null;
} catch (e) {
return null;
}
};
export default { storeItem, getItem };

React-native stack navigation not showing right screen

all, I am having a problem that my stack navigation is not showing any screen.
I have 'signup' and 'login' screens, and I build a stack navigator(which is the startStack) try to navigate between those two screens. But it doesn't work. when a user first come(if she hasn't logged in before), the 'login' screen should be shown.
Please help me out , I really appreciate , thank you.
this is the App.js
import React, { Component } from "react";
import "react-native-gesture-handler";
import { StyleSheet, Text, View } from "react-native";
import Login from "./screens/login";
import Signup from "./screens/signup";
import MyOrders from "./screens/myOrders";
import firebase from "firebase";
import StartNavigator from "./routes/startStack";
class App extends Component {
state = {
loggedIn: null,
};
componentDidMount() {
var firebaseConfig = {
apiKey: "AIzaSyASR4GAXSRGsiDhOTF_UsdqHzqHYcHPk_U",
authDomain: "onlineorderportal-68a8f.firebaseapp.com",
databaseURL: "https://onlineorderportal-68a8f.firebaseio.com",
projectId: "onlineorderportal-68a8f",
storageBucket: "onlineorderportal-68a8f.appspot.com",
messagingSenderId: "658149255251",
appId: "1:658149255251:web:37940844cdc5403e173ea6",
measurementId: "G-KGQ1F2F3WE",
};
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
} else {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.setState({ loggedIn: true });
} else {
this.setState({ loggedIn: false });
}
});
}
}
renderContent = () => {
switch (this.state.loggedIn) {
case false:
console.log("false case login");
// return <Login />;
// return <Signup />;
return <StartNavigator />;
case true:
console.log("true case Navigator");
return <MyOrders />;
}
};
render() {
return (
<View style={styles.container}>
{this.renderContent()}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#FFFFFF",
alignItems: "center",
justifyContent: "center",
},
});
export default App;
This is the startStack.js
import React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import { NavigationContainer } from "#react-navigation/native";
import Login from "../screens/login";
import Signup from "../screens/signup";
const Stack = createStackNavigator();
function StartNavigator() {
console.log("enter Start");
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
<Stack.Screen name="Signup" component={Signup} />
<Stack.Screen name="Login" component={Login} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default StartNavigator;
When I try to return 'Login' or 'Signup' separately, it correctly show the pages separately.
Thank you so much !!!
You have created StartNavigator, which has only two screens 'Login' and 'Singup'. And you have set initialRouteName as 'Login'. So your 'App' component never called. So all the code that you written on App component never run. To work this add App component in your StartNavigator and set initialRouteName to app like below :
import React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import { NavigationContainer } from "#react-navigation/native";
import Login from "../screens/login";
import Signup from "../screens/signup";
import App from "../app/path"; // import App here
const Stack = createStackNavigator();
function StartNavigator() {
console.log("enter Start");
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
<Stack.Screen name="App" component={App} /> // add app component
<Stack.Screen name="Signup" component={Signup} />
<Stack.Screen name="Login" component={Login} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default StartNavigator;
Did you check conditions after receive data from the server?
what is the value of 'loggedIn'?
I think that the value of 'loggedIn' is not correct or your switch case is not working.
use console.log before doing any condition for sure that the value of 'loggedIn' is correct.