When signing out of my app the signin screen is getting rendered twice. This only happens when i navigate to another screen and then go back to the initialroute. If i do not leave the initialroute after login and logout right away it only renders once as it should. But as soon as i start navigating in my app then logout the signin screen gets rendered twice.
I am using redux in combination with asyncstorage to handle the authentication flow in my app. I have only found one person with the same problem and he solved it by using SwitchNavigator instead of StackNavigator as seen here but the SwitchNavigator has been removed in React Navigation 6 and i cant find a solution so all help is appriciated.
redux reducer for the user.js
import {UPDATE_USER} from '../actions/actionTypes';
const initialState = {
userdata: {},
loginStatus: -1, // -1 == loading, 0 = not logged in, 1 == logged in
};
const updateUser = (state, action) => {
let ud = action.userdata;
return {...state, userdata: Object.assign({}, ud), loginStatus: ud ? 1 : 0};
};
const userReducer = (state = initialState, action) => {
switch (action.type) {
case UPDATE_USER:
return updateUser(state, action);
default:
return state;
}
};
export default userReducer;
Loading screen.js
import React, {useEffect, useState, useRef} from 'react';
//ThirdParty
//import CustomSplashScreen from 'react-native-splash-screen';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {NavigationContainer} from '@react-navigation/native';
//Redux
import {updateUser} from '../../redux/actions/userActions';
import {useSelector} from 'react-redux';
import {useDispatch} from 'react-redux';
//Import STACK NAVIGATORS
import AuthNavigator from '../../navigator/AuthNavigator';
import MainNavigator from '../../navigator/MainNavigator';
function LoadingScreen() {
const ref = useRef();
const loginStatus = useSelector((state) => state.user.loginStatus);
const dispatch = useDispatch();
useEffect(() => {
console.log('loginStatus', loginStatus);
async function getAsyncData() {
let data = await AsyncStorage.getItem('data');
let dataParsed = JSON.parse(data);
console.log("AsyncData: "+data);
//Update redux state
dispatch(updateUser(dataParsed));
}
getAsyncData();
});
if (loginStatus === -1) {
// We haven't finished checking for the user logged in or not
return <View style={styles.container} />;
}
ref && ref.current && ref.current.animateNextTransition();
return (
<NavigationContainer>
<Transitioning.View ref={ref} transition={TRANSITION} style={styles.transitionContainer}>
{loginStatus === 1 && <MainNavigator />} // STACK NAVIGATOR WHEN SIGNED IN
{loginStatus === 0 && <AuthNavigator />} // STACK NAVIGATOR WHEN SIGNED OUT
</Transitioning.View>
</NavigationContainer>
);
}
export default LoadingScreen;
signoutFunction() inside screen
const signOutAsync = async () => {
console.log("Begin Logout");
dispatch(updateUser(null));
await AsyncStorage.clear();
};
It appeared that both navigators were mounted and affected by the login so i finally solved it by wrapping both Navigators inside a parent stack container like below.
Loading screen.js
const RootStack = createStackNavigator();
const RootStackScreen = () => (
<RootStack.Navigator screenOptions={{headerShown: false}}>
{loginStatus ? (
<RootStack.Screen name="Main" component={MainNavigator} />
) : (
<RootStack.Screen name="Auth" component={AuthNavigator} />
)}
</RootStack.Navigator>
);
return (
<NavigationContainer>
<Transitioning.View ref={ref} transition={TRANSITION} style={styles.transitionContainer}>
<RootStackScreen />
{/*loginStatus === 1 && <MainNavigator />*/}
{/*loginStatus === 0 && <AuthNavigator />*/}
</Transitioning.View>
</NavigationContainer>
);
Credits to: React native school
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With