Get Started with React Navigation 5 in React Native
By: Ross Bulat
Tags: React Native, Software Engineering, Programming, React, JavaScript

Navigator Components

There are 3 main navigators that React Navigation comes bundled with, that are suitable for both iOS and Android based projects. These navigators and their respective packages are as follows.

Stack Navigator

@react-navigation/stack (official doc): The most vanilla navigator you’ll find, a Stack navigator will navigate from screen to screen in a hierarchical fashion:

To set up a stack navigator, declare a stack navigator object via the createStackNavigator method. From here, the Navigator and Screen components derived from this method can be used to embed and wrap your desired screens:

import { createStackNavigator } from '@react-navigation/stack' const DashboardStack = createStackNavigator(); function Dashboard() {

return (

<DashboardStack.Navigator mode='modal' headerMode='none'>

<DashboardStack.Screen name="Home" component={HomeScreen} />

<DashboardStack.Screen name="Stats" component={StatsScreen} />

</DashboardStack.Navigator>

);

}

This pattern of declaring a new navigator and taking the resulting Navigator and Screen components is consistent throughout all the supplied navigators.

As you can see, the component-based declaration differs a lot from the previous version, but is quite self explanatory. Notice the mode and headerMode props of DashboardStack.Navigator — these may be familiar to you if you have used React Navigation 4.

Essentially, the navigationOptions properties are now represented as props, all of which have been documented here.

In addition to this, each DashboardStack.screen also support an options prop to customise navigation options on a per-screen basis. Instead of defining headerMode='none' fort the entire navigator, we could disable the header to individual screens using options :

<DashboardStack.Screen

name="Home"

component={HomeScreen}

options={{

headerShown: false

}}

/>

There are quite a few ways to manipulate the header through options — check out all the options properties here.

Bottom Tabs Navigator

@react-navigation/bottom-tabs (official doc): Another valuable navigator that will set up the boilerplate for a tab bar navigator, popular amongst dashboard designs. This tab bar navigator offers quite a comprehensive solution, allowing the developer to customise the look and feel of tabs with ease.

The following gist demonstrates how to construct a Bottom Tabs navigator, with some customisation with SVGs and styling:

Again, the bulk of syntax may look similar to the previous version of React Navigation, with a couple of key differences:

We’re now configuring the tabs within a screenOptions of the navigator component, where the tabBarIcon property is returned.

of the navigator component, where the property is returned. screenOptions now provides a route prop (more on that further down) that provides context on the currently active screen. This is now used in your switch statement to determine the icon SVG.

now provides a prop (more on that further down) that provides context on the currently active screen. This is now used in your switch statement to determine the icon SVG. The tabBar options prop is also a part of screenOptions, that allows you to configure additional styling of the tab bar.

Each Tab icon is embedded via JSX with a <BottomTabs.Screen /> component within the <BottomTabs.Navigator /> component.

All the props and more screenOptions examples are documented at the official docs, as well as a dedicated Tabs Navigation guide being available to read through.

Stack navigators can be nested within bottom tab navigators, but the bottom tabs UX will remain as you are navigating through the stack hierarchy. This may be what you intend to do, but in most cases, displaying tabs within deep hierarchies is confusing UX. To get around this, you can link from one screen to another screen in another navigator, that we’ll cover further down.

Drawer Navigator

@react-navigation/drawer (official doc): Another useful navigator that allows screens to animate from one side of the screen to be revealed, and animate back when closed. Stack navigators can be nested within these types of navigators to expand on the content within it:

The Drawer Navigation documentation does a good job covering this navigator, so this article will not delve deeper into it, having covered the previous two navigators that demonstrate the same changes from the previous version. There are some useful props for the Navigator however, beyond screenOptions , that will be commonly used, with openByDefault , drawerPosition , drawerType and minSwipeDistance being some of those.

For completeness, there are two more Android focussed navigators that based on Google’s Material theme design, being createMaterialBottomTabNavigator and createMaterialTopTabNavigator .

These navigators are typically managed by the organisation themselves on GitHub, that can be seen on their GitHub organisation page along with all the other utilities React Navigation offer.

Nesting Navigators

It is common to nest navigators within other navigators, and navigate from one to another. Consider the following setup where a stack navigators are nested within a tab bar navigator:

// nesting navigators const DashboardStack = createStackNavigator(); export const Dashboard = () => {

return (

<DashboardStack.Navigator>

<DashboardStack.Screen name="Home" component={HomeScreen} />

<DashboardStack.Screen name="Stats" component={StatsScreen} />

</DashboardStack.Navigator>

);

} const BottomTabs = createBottomTabNavigator(); export const Tabs = () => {

return (

<BottomTabs.Navigator

...

>

<BottomTabs.Screen name="Dashboard" component={Dashboard} />

<BottomTabs.Screen name="Settings" component={Schedule} />

);

}

What if we wanted to navigate from one tab to a particular stack screen in another tab? Well, React Navigation provides a simple API to do so, using the navigate function within the navigation prop. Consider the following button:

// navigating through nested navigators <Button

label="Back Home"

onPress={() => {

navigation.navigate('Dashboard', {

screen: 'Stats'

});

}}

/>

Upon pressing the above button, the tab bar navigator will switch to the Dashboard screen, and the stack navigator within that will navigate to the Stats screen.

More detail on nesting navigators can be found here.

About the new `route` prop

Although the navigation prop is still used in v5, some of its properties have been delegated to a separate route prop, as a means to separate the current route properties from the navigation context. The upgrading from v4 to v5 post has outlined these changes of the navigation prop.

The route prop (at props.navigation.route ), is now where the current screen’s data is hosted, that used to be in props.navigation.state .

Concretely, navigation supplies you with methods and context to navigate through your NavigationContainer , whereas route contains data pertaining to the currently active screen. For more info on these props:

Go to the navigation API reference, that lists all the properties of the object, ranging from goBack , navigate , setParams , and more.

API reference, that lists all the properties of the object, ranging from , , , and more. Go to the route API reference, that details its properties, including the name , key and params properties.

In regards to setting params when navigating, not much has changed. However, there is no more getParam method to fetch params. Instead, params are fetched from route.params in the following fashion:

// getting a param from `route` const myParam = route.params?.myParam ?? 'defaultValue';

This is a more generic way of checking whether a param exists and assigning a default value if it does not, rendering the previous getParam utility somewhat obsolete.

Hooks in React Navigation 5

There has also been an introduction of new hooks in React Navigation 5, that make it easier to work with navigators within functional components, as well as put less (or no) reliance on HOCs.

The useNavigation hook for example removes the need for the withNavigation HOC that was depended upon before, that will fetch the navigation object from the navigation container’s context:

// useNavigation hook import { useNavigation } from '@react-navigation/native'; function MyComponent() { // get navigation without passing it down in props

const navigation = useNavigation();

...

}

This totally replaces withNavigation , that is now a part of the Compatibility layer of utilities.

useRoute can also be used to obtain the route object discussed in the previous section. There are a few more hooks to be aware of when upgrading from v4:

useFocusEffect : triggered when the screen in question is focussed. This can replace an event listener setup that you may have relied upon in previous versions.

Event listeners are still supported, but have been simplified. There are now two events of navigation, focus and blur . Before, we had didFocus , willFocus , didBlur and willBlur to play with. focus can be implemented within useEffect like so:

let focusListener = null;

useEffect(() => {

focusListener = navigation.addListener('focus', async () => {

// do something

});



return (() => {

if (focusListener.remove !== undefined)

this.focusListener.remove();

})

}, []);

Notice that focusListener is null by default, as useEffect hooks are triggered after the component renders.