As part of refactoring and upgrading the code-base, our team decided to upgrade the React navigation version from 4.x to 5.x. Now this 5.x has completely new API, so the old code using React navigation 4.x will no longer work with this version. Moving the entire code-base navigation version to 5.x can be a lot of work.
To achieve this we have used the compat library, So that we can reuse code using the version 4.x with minimal changes. Then slowly started moving each navigator to the version 5.x. As part of this we started a round of testing to see if everything works fine but surprisingly we encountered few problems which are not described in official documents. So, we took a deep dive and see what causes the problem and here are a few findings:
navigation.state is undefined in v5:
In React Navigation 4.x, the navigation prop has various helper methods as well as the current screen's state.But In 5.x, the navigation prop splitted into 2 props: navigation and route. navigation prop contains helper methods such as navigate, goBack etc., and route prop contains the current screen's data which we previously accessed via navigation.state.
In version 4.x:
In version 5.x:
Header null not allowed:
Header is a React Element or a function which is part of the navigationOptions that is used to configure the header (Also known as navigation header i.e the rectangle at the top of the screen). If you want the header to be null
In version 4.x we can specify it as:
But in version 5.x If we specify it as null causing crashes. So In 5.x it should be a function that returns an empty component:
navigationOptions -headerLeft, headerRight, headerTitle should be function:
In React Navigation 4.x these navigationOptions can be a element as follows:
But in 5.x if we are specifying any of these navigationOptions as a element then they are causing the crashes. So we finally fixed this problem by specifying these navigationOptions as a function that returns a React element as follows:
Finding routeName in v5:
In React Navigation 4.x routeName is part of the navigation prop and that can be accessed as:
But in 5.x routeName is now part of the route prop and that is renamed to name which can be accessed as:
Navigating to a screen in a nested navigator:
The difference is that in the previous versions, all configuration was static, so React Navigation could statically find the list of all the navigators and their screens by recursing into nested configurations. But with dynamic configuration, React Navigation doesn’t know which screens are available and where until the navigator containing the screen renders. Normally, a screen doesn’t render its contents until you navigate to it, so the configuration of navigators which haven’t rendered is not yet available. This makes it necessary to specify the hierarchy you’re navigating to. This is also why you should have as little nesting of navigators as possible to keep your code simpler.
In 4.x all the navigation configurations were static. So React navigation can find the specified screen by recursing the list of all navigators and their screens in nested configurations.
For example lets take the following in which SettingsNavigator is nested inside ProfileNavigator ( To show how nested navigation works I am using the navigator configuration in 4.x version)
So, to navigate to the EditProfileScreen in 4.x navigate will look like :
But with dynamic configuration in 5.x, React navigation doesn’t know which screens are available and where until the navigator containing the screen renders. Normally a screen doesn’t render its contents until you navigate to it, so the configuration of navigators which haven’t rendered is not yet available. This makes it necessary to specify the hierarchy you’re navigating to. So to navigate to the EditProfileScreen we have to do as follows:
These are the few findings that our team has while upgrading React Navigation from 4.x to 5.x and which are not described much in documentation. I will continue to add few more findings in part-2. Thanks for reading.
Top comments (0)