Navigating between screens is a fundamental aspect of mobile app development, and in the realm of React Native, mastering navigation is key to creating a seamless user experience. In this article, we delve into the powerful combination of Stack Navigation and Tab Navigation in React Native.
We’ll construct a basic user flow for a typical authentication-based mobile app. Together, we’ll build a common initial sequence that integrates checking if the user is logged in, if it’s the first time, and redirect the user to the proper screen.
Graph 1. Flow diagram of the initial sequence.
The project and dependencies
Let’s create a bare React Native project with expo by running:
npx create-expo-app AppName --template bare-minimum
Install react navigation libraries. For more information, please visit the official documentation.
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
The idea
We’ll implement the flow outlined in Graph 1 using a structured approach. Our AppNavigation
serves as a StackNavigator
with three main children:
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
0,
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
1, and
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
2. Note that,
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
2 also functions as a
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
4 with three additional children:
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
5,
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
6, and
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
7. This hierarchical setup provides a clear and organized navigation structure for our application.
The solution
Then, let’s create the lower components, Home Tab, and its three screens: Page 1, Page 2, and Page 3.
// This is ReactNative hook to handle navigation // you can also receive it as a prop. I prefer this one. import { useNavigation } from "@react-navigation/native" import { Text, Button, View } from "react-native"
const Page = [] => {
const navigation = useNavigation[]
return
Page
navigation.reset[{ index: 0, routes: [{ name: 'Login' }] }]}
/>
}export default Page
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; // Import this from wherever your pages are located import Page from '@screens/Page'
// Attention, this is a BottomTab
const Tab = createBottomTabNavigator[]
return [
{ const navigation = useNavigation[]
return
Landing
navigation.reset[{ index: 0, routes: [{ name: 'Home' }] }]}
title='Sign In'
/>
}export default LoginScreen
import { useNavigation } from "@react-navigation/native"
import { View, Text, Button } from "react-native"
const OnBoarding = [] => {
const navigation = useNavigation[]
return
Welcome
navigation.reset[{ index: 0, routes: [{ name: 'Home' }] }]}
title='Go Home'
/>
}export default OnBoarding
Up to this point, our setup includes:
- Each
// This is ReactNative hook to handle navigation
// you can also receive it as a prop. I prefer this one.
import { useNavigation } from "@react-navigation/native"
import { Text, Button, View } from "react-native"
const Page = [] => {
const navigation = useNavigation[]
return
Page
navigation.reset[{ index: 0, routes: [{ name: 'Login' }] }]}
/>
}
export default Page
0 features a logout button that redirects users to the Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
0 screen. - // This is ReactNative hook to handle navigation
// you can also receive it as a prop. I prefer this one.
import { useNavigation } from "@react-navigation/native"
import { Text, Button, View } from "react-native"
const Page = [] => {
const navigation = useNavigation[]
return
Page
navigation.reset[{ index: 0, routes: [{ name: 'Login' }] }]}
/>
}
export default Page
2 acts as a
// This is ReactNative hook to handle navigation
// you can also receive it as a prop. I prefer this one.
import { useNavigation } from "@react-navigation/native"
import { Text, Button, View } from "react-native"
const Page = [] => { const navigation = useNavigation[]
return
Page
navigation.reset[{ index: 0, routes: [{ name: 'Login' }] }]}
/>
}
export default Page
3 holding three distinct screens [
// This is ReactNative hook to handle navigation
// you can also receive it as a prop. I prefer this one.
import { useNavigation } from "@react-navigation/native"
import { Text, Button, View } from "react-native"
const Page = [] => { const navigation = useNavigation[]
return
Page
navigation.reset[{ index: 0, routes: [{ name: 'Login' }] }]}
/>
}
export default Page
0]. - The
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
9 screen has a button to reset the navigation tree, guiding users back to the
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
2 screen. - In the
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
0 screen, a simulated sign-in button is in place, triggering a navigation tree reset that leads users back to the
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
2 screen as well.
Putting all together
Let’s plug the final piece, the AppNagivation
// This is ReactNative hook to handle navigation
// you can also receive it as a prop. I prefer this one.
import { useNavigation } from "@react-navigation/native"
import { Text, Button, View } from "react-native"
const Page = [] => {
const navigation = useNavigation[]
return
Page
navigation.reset[{ index: 0, routes: [{ name: 'Login' }] }]}
/>
}export default Page
9 . This one is going to hold the three screens on the second layer we previously created,
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
0,
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
2, and
Install the core library
npm install @react-navigation/native
Install the dependencies
npm install react-native-screens react-native-safe-area-context
Install Navigation Stack
npm install @react-navigation/native-stack
Install Bottom Tabs
npm install @react-navigation/bottom-tabs
9 .
Source Codeimport { createNativeStackNavigator } from '@react-navigation/native-stack'
import { NavigationContainer } from '@react-navigation/native'
// Screens we previously created
import HomeNavigation from './HomeNavigation'
import LoginScreen from '@screens/LoginScreen'
import OnBoarding from '@screens/OnBoarding'
const AppNavigation = [{ initialRoute }] => {
// Attention, this is a Stack
const Stack = createNativeStackNavigator[]
// Please refer to the Graph2, where all modules are connected
return [
]
}export default AppNavigation
As you can see, the AppNavigation has a prop named
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
// Import this from wherever your pages are located
import Page from '@screens/Page'
const HomeNavigation = [] => { // Attention, this is a BottomTab
const Tab = createBottomTabNavigator[]
return [
{ // Attention, this is a BottomTab
const Tab = createBottomTabNavigator[]
return [
{ // Attention, this is a BottomTab
const Tab = createBottomTabNavigator[]
return [
{ // Attention, this is a BottomTab
const Tab = createBottomTabNavigator[]
return [
{ // Attention, this is a BottomTab
const Tab = createBottomTabNavigator[]
return [
{ return { const timeout = setTimeout[[] => {
setIsLoading[false]
}, 2000]
return [] => { clearTimeout[timeout] }
}, []] // Calculate what the initial route is going to be, depending
// on the user state, and first time usage. This can be read
// from anywhere, db, shared preferences, user defaults, storage, etc.
const initialRoute = [] => {
if [isLoggedIn] return 'Home'
if [isFirstTime] return 'OnBoarding'
return 'Login'
} if [isLoading] return
return
}
export default App
Source Code
In this GitHub repository, you can find the whole project including implementation details we didn’t cover in this article. If you want to dive deeper into the documentation, visit the official React Native, and React Navigation sites.
Thanks for reading. I hope you have enjoyed this small tutorial, and if it was useful for you, don’t be shy to 👏 on this article. See you next time.