Hi I am trying to add Tab Navigation when user is logged in and Stack Navigation when User is not logged in. So I have wrote a logic but I don't know why I am getting errors. Kindly help me out.
I wanted to show Tab Navigation only when user has successfully logged in I am using Nodejs backend and Mongodb as database.
This is my AppNavigator file.
AppNavigator.js
import React, { useEffect, useState } from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import { NavigationContainer } from '@react-navigation/native';
import SignUp from "../screens/SignupScreen";
import LoginScreen from "../screens/LoginScreen";
import LoadingScreen from "../screens/LoadingScreen";
import HomeScreen from "../screens/HomeScreen";
import AsyncStorage from '@react-native-async-storage/async-storage';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator()
const [isLoggedin, setLogged] = useState(null)
const TabNavigator = () => {
return <TabNavigator>
<Tab.Screen name='Home' component={HomeScreen} />
<Tab.Screen name='Profile' component={AccountScreen} />
<Tab.Screen name='Home' component={HomeScreen} />
</TabNavigator>
}
const AuthNavigator = () => {
return (
<Stack.Navigator
headerMode="none"
screenOptions={{
headerStyle: { elevation: 0 },
cardStyle: { backgroundColor: '#fff' }
}}
>
<Stack.Screen name="loading" component={LoadingScreen}></Stack.Screen>
<Stack.Screen name="home" component={HomeScreen}></Stack.Screen>
<Stack.Screen name="login" component={LoginScreen}></Stack.Screen>
<Stack.Screen name="signup" component={SignUp}></Stack.Screen>
</Stack.Navigator>
)
};
const Navigation = () => {
const [user, setUser] = useState('');
useEffect(() => {
if (isLoggedin) {
setUser(userExist)
}
else {
setUser('')
}
}, [])
return (
<NavigationContainer >
{user ? <TabNavigator /> : <AuthNavigator />}
</NavigationContainer>
)
};
function AppNavigator() {
useEffect(() => {
const token = AsyncStorage.getItem('token')
if (token) {
setLogged(true)
}
else {
setLogged(false)
}
}, [])
return (
<Navigation />
);
}
export default AppNavigator;
This is my App.js file
App.js
import React,{useEffect,useState} from "react";
import { NavigationContainer } from "@react-navigation/native";
import AppNavigator from "./navigation/AppNavigator";
export default function App() {
return (
<AppNavigator />
);
}
I have my own LoadingScreen file
LoadingScreen.js
import { StatusBar } from 'expo-status-bar';
import React,{useEffect,useState} from 'react';
import { StyleSheet, ActivityIndicator, Image,View,Text } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Button, TextInput } from 'react-native-paper';
// <View style={styles.container}>
export default function LoadingScreen(props) {
const detectLogin = () =>{
const token = AsyncStorage.getItem('token')
if (token) {
props.navigation.navigate("profile")
}
else {
props.navigation.navigate("login")
}
}
useEffect(() => {
detectLogin()
}, [])
return (
<View style={styles.container}>
<ActivityIndicator size="large" color="black">
</ActivityIndicator>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I've created a Snack for you to see the working example
The first thing that I Noticed is that in your
TabNavigator
function you wroteInstead you have to write something like this
Your token restoration logic is not efficient I guess.
I would suggest you to make two different
Navigators
and performtoken checking
logic inside yourApp.js
What you should do is, create a folder called
navigation
where yourApp.js
is located.Then inside
navigation
create two filesAppNavigator.js
andAuthNavigator.js
Your
AppNavigator.js
should look like this -Your
AuthNavigator.js
should look like this -Then you should install
expo-app-loading
from hereThen in your
App.js
This is the most efficient way of authentication that I use in all my projects..