React Navigation 5
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 thenavigation
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 objectuseNavigationState
— 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'suseEffect
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 andScrollView
. - Simpler API for
reset
action where you can pass the new state directly instead of a chain of actions. - More reliable
focus
andblur
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!