React Navigation 6 keeps mostly the same core API as React Navigation 5, and you can think of it as further polishing what was in React Navigation 5. Let's talk about the highlights of this release in this blog post.
Navigators accept many of their customization options as props, which means we can’t customize them based on the active screen. To make this level of control possible, we needed to move these props to options that you can configure per screen.
In React Navigation 6, many of these props are now screen options. The most significant changes are
drawerContentOptions, which now all live on
options instead. For example:
See deprecations for more details.
We extracted some of the components and helpers used across various navigators in React Navigation and published them under a new package called
@react-navigation/elements. It can be useful if you're building your own navigator, or just want to reuse some of the components in your app.
Currently only a small set of components are exported, but there are more to come.
We simplified many APIs with React Navigation 6 to address common use cases. For example:
- Single option to use a modal presentation style and transparent modal with
- Custom header doesn't require setting
useHeaderHeighthook now ignores hidden headers and returns the height of the closest visible header in parent
- New option to set a custom background (such as
BlurView) for tab bar without having to use a custom tab bar
- New API to manage ref on the container (
Group component for organization#
Group component helps you organize screens inside your navigators and share common
screenOptions between the
screenOptions to a group configures all the screens inside that group to use these options. You can override
Group options by passing
options to each Screen component, similar to how you can with
screenOptions on Navigator. You can also nest
Group components inside other
Group components. They are lightweight and don’t render anything - like fragments, so they won’t affect performance.
In this code snippet, you can see that we group regular screens under one group and modal screens under another group:
Developers often want to show a header for screens inside of drawers and bottom tabs. To do this, we had to nest a stack navigator which provides a header, even if it was a navigator with just one screen. So we now show headers by default in screens of drawer and bottom tabs. No nesting necessary.
We also export a
Header component in the new elements library to use anywhere in your components.
Animated. While this works for a lot of apps, apps with heavy screens can suffer from poor performance, and some native features are difficult to re-create exactly (such as the large header on iOS). So, we wanted to address this by using native primitives for navigation.
With React Navigation 5, we introduced
@react-navigation/native-stack package powered by
react-native-screens, as well as a native backend for
@react-navigation/material-top-tabs powered by
In React Navigation 6, we made
@react-navigation/native-stack the default choice for setting up Stack navigation. It uses
UINavigationController on iOS and Fragments on Android to implement navigation natively. We also focused a lot on aligning the API of
@react-navigation/stack so that it’ll be easier to switch between them.
@react-navigation/native-stackis now used as the default choice in the documentation, it doesn't replace
@react-navigation/stack. Both packages are maintained and are valid options for your projects. If you're currently using
@react-navigation/stack, you can keep using it. You don't need to move to
@react-navigation/native-stackunless you really want to.
Similarly, we switched
@react-navigation/material-top-tabs to use
react-native-pager-view by default.
React Navigation 5’s TypeScript support was much better than React Navigation 4; but, some things such as
useNavigation were still untyped by default.
In React Navigation 6, you don’t need to annotate
useNavigation to get autocompletion and type checking. This is possible by defining a type for the screens globally using declaration merging:
You can read more about it in our TypeScript docs.
Our new Flipper plugin includes similar functionality to the currently available Redux Devtools Extensions integration. You can see all navigation actions, and jump back and forth between earlier and new navigation states. In addition, it also includes a tab to test your linking configuration.
Since the dev tools is built from scratch, we’re now free to add new features to make debugging easier in future.
One advantage of the Flipper plugin over Redux Devtools Extension is that it doesn’t need Chrome Debugger to work. Since Chrome Debugger can sometimes affect performance and even potentially change behavior, we think this is a more reliable solution.
While React Navigation 6 doesn't introduce changes of the same magnitude as React Navigation 5, there are still some breaking changes. It is possible, however, to mix packages from React Navigation 5 and React Navigation 6 (with a few caveats) so that you can gradually upgrade packages.
See the upgrade guide for a full list of changes and more details.
If React Navigation helps you to deliver value to your customers, it'd awesome a lot if you could sponsor us. Sponsorships will help us to move more quickly towards our goal of building the best cross-platform navigation library and continue to provide timely support for bug reports in our GitHub issues.