There’s some logic issue with my stack when I’m trying to login and logout. I’m currently storing a token using AsyncStorage, however, it seems to be a problem of going into another navigation stack and I’m not quite understanding it. I have verified that the token is showing up as intended and being wiped out as the login/logout action gets triggered.
Main Nav Stack:
<NavigationContainer>
<RootStack.Navigator>
{
token !== null ?
(
<>
<RootStack.Screen name="tabnav" component={BottomTabNavigator} options={{ headerShown: false }} />
<RootStack.Screen name="create-profile" component={CreateProfile} options={{ headerShown: true }} />
<RootStack.Screen name="profile" component={Profile} options={{ headerShown: true }} />
</>
) :
(
<>
<RootStack.Screen name="test" component={UnauthenticatedRoutes} />
</>
)
}
</RootStack.Navigator>
</NavigationContainer >
Tab Nav
const BottomTabNavigator = () => {
const Tab = createBottomTabNavigator()
return (
<Tab.Navigator
screenOptions={{
headerShown: true,
headerStyle: { backgroundColor: '#FB5B5A' },
headerTintColor: 'white',
headerTitle: () => (
<Image
resizeMode='center'
style={{
width: 20, height: 20, backgroundColor: '#FB5B5A'
}}
source={require('../assets/ios/rocket-lunch.png')}
/>
),
tabBarActiveTintColor: '#FFF',
tabBarActiveBackgroundColor: '#FB5B5A'
}}>
<Tab.Screen name="Dashboard" component={Dashboard} options={{
tabBarIcon: ({ }) => (
<Icon name="mobile-phone" size={30} />
)
}} />
<Tab.Screen name="Settings" component={Settings} options={{
tabBarIcon: ({ }) => (
<Icon name="gear" size={30} />
)
}} />
</Tab.Navigator>)
Login which uses the navigation object to re-route
const Login = () => {
const [email, onEmailChange] = useState('')
const [password, onPasswordChange] = useState('')
const navigation = useNavigation()
const [login] = useMutation(LOGIN_MUTATION, {
variables: {
input: {
email,
password,
}
},
onCompleted: async (newData) => {
try {
await AsyncStorage.setItem("token", newData.login.token)
await AsyncStorage.setItem("email", newData.login.email)
navigation.navigate('tabnav')
} catch (e) {
console.error(e)
}
}
})
Logout which uses the navigation object to re-route
case 'Logout': {
logoutUser()
navigation.navigate('login')
AsyncStorage.clear()
break
}
I get complaints of "The action ‘NAVIGATE’ with payload {"name":"tabnav"} was not handled by any navigator, also getting it for the logout case function as well. Is this a timing issue?
1
1 Answer
Not a timing issue. When you are not logged in your navigator doesn’t "see" the tabnav
route – it’s excluded from your navigator by the ternary token !== null ?
. The opposite is true when you’re logged in – you can’t see the unauthenticated routes. Therefore you can’t switch from one to the other.
Updating AsyncStorage won't trigger update of states in react-native. You will need a global state management library (Redex / Context) to handle this kind of login flow. See react-navigation doc.
58 mins ago