React Native Navigation & Authentication Flow — Step-by-Step Guide!
This guide walks through how to conditionally render authenticated vs unauthenticated navigation stacks in a React Native app, based on an accessToken stored in AsyncStorage.
🧩 Overview
To implement authentication-based navigation:
- Retrieve
accessTokenfromAsyncStorage. - Show a loading screen until token retrieval is complete.
- Render appropriate navigation stack based on the presence of the token.
📦 Dependencies
Ensure you have these installed:
npm install @react-native-async-storage/async-storage
npm install @react-navigation/native @react-navigation/native-stack- Storage Utility
- Create a utility file to read from
AsyncStorage.
// storage.ts
import AsyncStorage from '@react-native-async-storage/async-storage';
export const getData = async (key: string) => {
try {
const value = await AsyncStorage.getItem(key);
return value;
} catch (e) {
console.error('Failed to retrieve value', e);
return null;
}
};🧠 2. Authentication-aware App Entry Point
Get Ajay T S’s stories in your inbox
Join Medium for free to get updates from this writer.
Modify your App.tsx to load the token and render navigation accordingly.
// App.tsx
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, View } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { RootNavigation } from './RootNavigation';
import { stackNames } from './core-constants';
import { getData } from './storage';
function App(): React.JSX.Element {
const [accessToken, setAccessToken] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const checkAccessToken = async () => {
const token = await getData('accessToken');
setAccessToken(token);
setLoading(false);
};
checkAccessToken();
}, []);
if (loading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" />
</View>
);
}
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<SafeAreaProvider>
<RootNavigation
initialRouteName={
accessToken ? 'HomeStack': 'LoginStack'
}
/>
</SafeAreaProvider>
</GestureHandlerRootView>
);
}
export default App;3. Root Navigation Setup
Define your root navigator to accept an initialRouteName and dynamically render screens.
// RootNavigation.tsx
import React from 'react';
import { NavigationContainer, createNavigationContainerRef } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { ActivityIndicator } from 'react-native';
import SplashScreen from 'react-native-splash-screen';
interface RootNavigationProps {
initialRouteName: string;
}
const RootNavigationStack = createNativeStackNavigator();
export const navigationRef = createNavigationContainerRef();
export const RootNavigation = ({ initialRouteName }: RootNavigationProps) => {
const onReady = () => {
SplashScreen.hide();
};
const routes = [
{ name: 'HomeStack', component: HomeStack },
{ name: 'LoginStack', component: LoginStack },
// ... add other stacks
];
return (
<NavigationContainer
ref={navigationRef}
theme={navigationTheme}
fallback={<ActivityIndicator size="large" color={MD2Colors.blue700} />}
onReady={onReady}
>
<RootNavigationStack.Navigator
initialRouteName={initialRouteName}
screenOptions={{ gestureEnabled: false }}
>
{routes.map(route => (
<RootNavigationStack.Screen
key={route.name}
name={route.name}
component={route.component}
options={{ headerShown: false }}
/>
))}
</RootNavigationStack.Navigator>
</NavigationContainer>
);
};Conclussion
✅ When a valid accessToken exists:
- App navigates to the (authenticated) home stack.
❌ If no token is found:
- App launches into the login flow.
By leveraging AsyncStorage and conditional navigation, you've implemented a simple yet effective authentication flow in your React Native app. This setup ensures users are directed to the appropriate screen based on their authentication status, providing a smoother and more secure user experience.
Happy coding!
Ajay T S








