React Navigation is used to navigate between app screens. It is nearly similar to websites where we click on links to open different pages. In this guide, you will learn the implementation of React navigation library in 10 minutes. So, let’s get started.
First of all you should know about the standard page transitions in mobile apps. They are –
-
Stack Navigation – One screen is visible to user at a time.
-
Tab Navigation – This kind of navigation helps in keeping the fixed parts of application visible while only changing the tab contents.
-
Drawer Navigation – Drawers helps in organizing the menu list and other frequently used options.
-
Modal Navigation – Modals do not change the current screen. They appear in front of it only. These modals have listener for back button. We use them to display short information or for doing a specific task like login form.
All the standard transition animations are inbuilt.
Learn more about React Native animations.
Installation of React Navigation
All the navigators are stored separately in this library. So, if you don’t want to use drawers in your app then there is no need to install drawer component. Apart from this, there is one core package which we need to install and include in our project.
Use yarn or npm to install core library and other required dependencies –
yarn add @react-navigation/native
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
If you want to use stack navigator, then install that using below command –
yarn add @react-navigation/stack
Similarly, you may install Tab and Drawer Navigator –
yarn add @react-navigation/bottom-tabs
yarn add @react-navigation/drawer
For modal, we don’t require a different package. Stack navigator handles that.
The first step after installation
The core library provides a higher order component (HOC) NavigationContainer
which is the starting point for us. We need to wrap our whole application inside this component. The best place to do that is either index.js
or app.js
.
import 'react-native-gesture-handler'; import * as React from 'react'; import { NavigationContainer } from '@react-navigation/native'; export default function App() { return ( <NavigationContainer> {/* Rest of your app code */} </NavigationContainer> ); }
Note: You need to import react-native-gesture-handler before any code (in this file). Otherwise your app may crash in production.
Here we have imported NavigationContainer
from native package. Then, we are wrapping our whole app inside it.
Understanding Stack Navigator
You should know that everything will be done within our NavigationContainer
now. You need to frame your react application according to the kind of navigation you need.
For example, you can have drawer for menu, tabs to display lists, modal for forms etc.
Stack navigator completely replaces one screen with another. But, this happens for a similar group of screens only. Let me explain this.
Suppose you have created tabs in your app. One tab can show you news feed as well as let you add a news too. While creating a news you might wish to hide the feed. But this all is happening inside a single tab. So, you have created a stack navigator (of news feed screen and news add screen) inside one tab screen of tab navigator. This stack navigator will completely hide (only news feed screen or news add screen). Tabs and other parts of app will remain untouched.
Using Stack Navigator in App
First of all we need to import the package. We need a specific function, createStackNavigator
.
import { createStackNavigator } from '@react-navigation/stack';
This function returns two components – Navigator
and Screen
. We can store the returned result in a constant, let’s say “Stack”.
const Stack = createStackNavigator(); /* Now we can use Stack.Navigator and Stack.Screen */
Each Screen
component renders single screen while Navigator
acts as a wrapper.
<Stack.Navigator> <Stack.Screen ... /> <Stack.Screen ... /> </Stack.Navigator>
Structure of Stack.Screen
is –
<Stack.Screen name={name of screen} component={screen component to render} options={other options object} />
This infographic will clear your understanding –
Above infographic shows 3 screens – Home
, Details
and Profile
. They are defined by Stack.Screen
and wrapped in Stack.Navigator
(See yellow box). Each screen is identified by name
prop in Stack.Screen
component. initialRouteName
prop in Stack.Navigator
indicates about the first screen. That’s why Home
screen has no back arrow button on navigation bar while Details
and Profile
have.
If you want to customize your navigation bar then there are multiple options available. In Details
screen we changed the background color, title size & color, and added a button on right side.
Similarly, on Profile
screen we changed the title with an image logo.
Navigation Between Screens
Each screen has a name. We define that in name
prop. This name is used to navigate to that screen.
There are few functions provided by library for this task. You may use any one of them depending on situation –
- props.navigation.navigate(New Screen Name) – Navigate to new screen.
- props.navigation.push(New Screen Name) – Push a new screen on top of history stack.
- props.navigation.goBack() – Go back to previous screen. Back button in mobile imitate this.
- props.navigation.popToTop() – Go back to first screen.
In our example (Dark orange box in infographic), we jumped from Home
to Details
page on press of a button.
Passing Data Between Screens
When we navigate between screens using props.navigation.navigate
, we can provide second argument as a data object.
props.navigation.navigate('Details', { id: 56 })
Details
screen can access this data using props.route.params
. So, it can get id
value using props.route.params.id
.
Updating own options by mounted screen
Suppose there is a comments screen. The title of navigation bar shows number of comments. Currently there are 10 comments so title says 10. You added 1 more so, technically the title should update to 11. But, it won’t happen because we are setting the options only while defining Screen
.
We can update options like title, header styles, title styles etc. from current screen too using props.navigation.setOptions
. Check this code –
props.navigation.setOptions({ title: 'New Title' });
Working with modal
We need to design our application navigation architecture in such a way that modal could be included at root screen.
Define a stack.navigator
and set its mode
prop to “model”. Include 2 screens. First one should render another stack navigator which will include all the screens of app. Second one will render the modal. Look at this code –
<Stack.Navigator mode="modal"> <Stack.Screen name="Main" component={MainStackScreen} options={{ headerShown: false }} /> <Stack.Screen name="MyModal" component={ModalScreen} /> </Stack.Navigator>
Understanding Tab Navigation
Tab navigation provides a tab based interface. We need to include createBottomTabNavigator
function from its package. Check out the code –
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; const Tab = createBottomTabNavigator(); export default function App() { return ( <NavigationContainer> <Tab.Navigator> <Tab.Screen name="Home" component={HomeScreen} /> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> </NavigationContainer> ); }
To add badges to the icons –
<Tab.Screen name="Home" component={HomeScreen} options={{ tabBarBadge: 3 }} />
To jump from one tab to another –
props.navigation.navigate('Settings')
Changing tab options –
<Tab.Navigator screenOptions={{tabBarIcon: <Icon ... />}} tabBarOptions={{ activeTintColor: 'tomato', inactiveTintColor: 'gray', }} />
Understanding Drawer Navigation
It is used to create a drawer. We need to include createDrawerNavigator
function. Check out code –
import { createDrawerNavigator } from '@react-navigation/drawer'; const Drawer = createDrawerNavigator(); export default function App() { return ( <NavigationContainer> <Drawer.Navigator initialRouteName="Home"> <Drawer.Screen name="Home" component={HomeScreen} /> <Drawer.Screen name="Notifications" component={NotificationsScreen} /> </Drawer.Navigator> </NavigationContainer> ); }
Use these functions to toggle, open and close the drawer –
props.navigation.toggleDrawer(); props.navigation.openDrawer(); props.navigation.closeDrawer();
Use this code to check if drawer is open or close –
import { useIsDrawerOpen } from '@react-navigation/drawer'; const isDrawerOpen = useIsDrawerOpen();
To learn more about React Navigation library please use https://reactnavigation.org/