React Navigation 5

Madalina Chis
Corebuild Software
Published in
5 min readMay 20, 2020

React Navigation 5 comes with a completely new way of navigating in your React Native app.

The main changes that come with this new version are:

  • component based configuration
  • new hooks
  • update navigation options from component/function
  • new theming API

We’ll take these new improvements step by step and explain them with examples later but now let’s start with the installation.

Installation

React Navigation 5 has even a new way of installing it and it looks like this:

// yarn
yarn add @react-navigation/native
// npm
npm install @react-navigation/native

Most navigators use many third party libraries for animations or transitions handling and in order to make this work we will also need to install those libraries.

// yarn 
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
// npm
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

Component Based configuration

The most important change in React Navigation 5 is that now all of the configuration happens inside a component and is dynamic.

NavigationContainer is a component which manages our navigation tree and contains the navigation state. This component must wrap all navigators structure.

After that we have to call createStackNavigator that returns an object containing 2 properties: Screen and Navigator.

Stack.Navigator is a component that takes route configuration as its children with additional props for configuration and renders our content.

Each Stack.Screen component take a name prop which refers to the name of the route and component prop which specifies the component to render for the route. These are the 2 required props.

To specify screen-specific options, we can pass an options prop to Stack.Screen, and for common options, we can pass screenOptions to Stack.Navigator

In the example above I created two nested navigators: a stack navigator that has a tab navigator inside. If you want to customize your screen options here is an example of customization for the tab navigator:

I added different icons based on the route name and focus state and different colors if the tabs are active or inactive.

New Hooks

The new API introduced a couple of new hooks for common use and they are a real time safer.

  • useNavigation — gives access to navigation object and it’s useful when you cannot pass the navigation prop into the component directly, or don't want to pass it in case of a deeply nested child
  • useRoute — gives access to the route object
  • useNavigationState — gives access to the navigation state of the navigator which contains the screen. It’s useful in rare cases when you want to render something based on the navigation state.
  • useFocusEffect — it’s like the React's useEffect hook, the only difference is that it only runs if the screen is currently focused.
  • useIsFocused — returns the current focus state of the screen. Using this hook triggers a re-render for the screen when it changes focus
  • useLinking — helps us handle the deep links in the apps

As useLinking is a bit complicated you will probably use the linking prop on the NavigationContainer as it accepts the same options as useLinking. You can set another useful prop to NavigationContainer: fallback that gets a React Element to display as fallback while deep links are resolved.

See configuring links guide for more details on how to configure deep links and URL integration.

  • useScrollToTop — gets a ref to a scrollable component as parameter and will scroll to top when navigating to the active tab

Update navigation options from component/function

The navigation props has now a new method called setOptions to configure screen navigation options easier than before (the static navigationOptions).

This new feature is useful if we have a dynamic header and want to add different buttons with different functionalities which have to interact with the screen state.

In this example I added a “Done” button to the header when a specific button is pressed.

New Theming API

The customization of your app theme is now much easier because it’s possible to provide a theme object to the NavigationContainer with your desired colors for background, accent color, text etc.

There are two operating system themes DefaultTheme and DarkTheme that can be used based on your app scheme or you can declare your custom theme and use it in the app by passing it to the NavigationContainer’s theme prop.

If you decided to declare your own app theme you can use it afterwards in your own components. Just use the useTheme hook and this will return the theme object.

Other changes

  • First-class types with Typescript: the new version has been written in TypeScript and that means that now we get first class autocompletion and type-checking.
  • Redux DevTools integration — If you use React Native Debugger or Redux Devtools Extension, you can see navigation actions in the devtools along with the current navigation state and it also supports time-travel debugging
  • Native stack navigator — The major change is that now “React Navigation meets native” and this means that if up until now React Navigation was written only in JavaScript replicating native animations and interactions, now they exported the native stack (FragmentTransaction on Android and UINavigationController on iOS) in order to deliver an even better native-like experience. 🎉 Thanks to the react-native-screens library now we can use truly native components instead of JS replicas.
  • Native backends for material top tab navigator — Similar to native stack, there are new backends for Material top tab navigator based on react-native-viewpager library and ScrollView.
  • Simpler API for reset action where you can pass the new state directly instead of a chain of actions.
  • More reliable focus and blur events to know when a screen's focus state changes.
  • Integration with InteractionManager to delay tasks until animation is complete.
  • Better safe area handling with react-native-safe-area-context.

Conclusions

React Navigation 5 comes with a lot of changes and the best advice is to upgrade to it as soon as possible or if you are starting a new project it’s better to start directly with React Navigation 5 to take advantage of all the new APIs and features that will simplify your code.

Here are the steps that can help you to upgrade from React Navigation 4 to 5: https://reactnavigation.org/docs/upgrading-from-4.x/

The entire sample app can be checked here.

Hope I convinced you to use React Navigation 5 in the future!

--

--