Findings while upgrading React Navigation from 4.x to 5.x (Part-1)
Tags: javascript, react, reactnative, typescript
Published: 2020-07-21 17:41:47

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](https://reactnavigation.org/docs/compatibility/) 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:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l6l47bu5v6s6c6nl0qjd.png)
####In version 5.x:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/oa5kbpq6gw53rrit37b1.png)
##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:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/g85u0osgz7mrclbylma5.png)
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:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/aw4ggis0rfnw8r4itwyc.png)
##navigationOptions -headerLeft, headerRight, headerTitle should be function:
In React Navigation 4.x these navigationOptions can be a element as follows:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pasbdsv3k2mir64442ra.png)
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:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gwee9siui697ojx5vtdq.png)
##Finding routeName in v5:
In React Navigation 4.x routeName is part of the **navigation** prop and that can be accessed as:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1mm5c0vv46us4gvma3hz.png)

But in 5.x routeName is now part of the route prop and that is renamed to name which can be accessed as:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5jxas592w4adfbw0nppr.png)

##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)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fpc394in0ntcb4hqmi4i.png)

So, to navigate to the EditProfileScreen in 4.x navigate will look like :

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gt1c6fw3tg3dcwlx4crm.png)


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:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wjoxbhiejv7vn4251qks.png)

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.