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>
}