Upgrading from React Navigation v1 to v2
How hard is it to upgrade on React Native?
As you may or may not know, navigation is the treadmill of React Native. Navigating what sounds like a simple library has proven to be an ongoing Sisyphean struggle. Fortunately for us all, the progress has continued on and the stalwarts of React have reached a new frontier.
Q: How hard is it to switch from 1.5.8 to 2.0?
A: Not hard at all! Here’s what I did.
Step 1: Upgrade React Native — ☠️ BEWARE 0.54.x
This seems like strange advice, but React Native 0.54.x shipped with a bug in the way React Context should be used. If you’re 0.54 or below, consider upgrading to ≥0.55 now. Yes, ≤0.53 will work, but you’ll forever have that landmine waiting, so just upgrade!
I lost a day to strange errors like “evaluation ‘context.changeBits’” and more. The actual issue was a rarely tripped bug in that version of React Native. If this article saves one person from the drudgery of those errors, then I’m happy. UPGRADE NOW!
Step 2: Navigators are Verbs
Everywhere you had StackNavigator
, DrawerNavigator
, or TabNavigator
should now become createStackNavigator
, createDrawerNavigator
, or createTabNavigator
instead. This is a straightforward find/replace. Don’t miss any; the errors won’t be clear.
It’s worth noting that Tab/Drawer are on their way out of the core library. Even now, the code for TabNavigator lives outside the repo. One day soon, you could install React Navigation and then follow up with installing
react-navigation-tabs
separately.
Step 3: Managing Nav State Yourself
Why?
If you were a power-user, it’s very likely you hooked your navigation state to your Redux or MobX-State-Tree, rather than leaving it blackbox. As a company, we did this in all our projects for two reasons:
- To view and manage navigation state in Reactotron.
- To persist navigation state so a user could return immediately in the same location when the app is restarted.
It’s worth noting that item two, state persistence, has now been added as a core feature of React Navigation 2.0. If you want to keep your navigation state integrated into Navigation 2.0, it’s not hard to do, but the reasons for doing this seem to be dwindling.
Changes
If you have already hooked up your code, then where you would normally call addNavigationHelpers
and pass an Object with dispatch
, state
, and addListener
has simply turned into an object.
You might notice that we were using lodash.throttle in our dispatch! As many of you 1.x users know, button-mashing was a nightmare on the old navigation. Now in 2.0, throttling comes built-in, so you can remove your protective throttle code.
That’s all I had to do to update our connected MobX-State-Tree integration. This default integration will ship with all Ignited projects on the Bowser stack.
Step 4: Breaking API Nits
There are small breaking API changes that are too numerous to list here. Small runtime errors will happen when these issues show their face. I’ve cherry-picked two things to identify for this blog:
- For me, the
headerBackImage
navigation option changed from a URI to a component. This simply meant that rather than providing an image, I had to provide an<Image/>
instead. This is the typical type of headache associated with a major API version upgrade, and the pain is minimal. - Another minor change worth noting is that
NavigationActions.reset
jumped over toStackActions.reset
. NavigationActions still exists.
Step 5: Never Believe Everything in a Blog Post
This post is a single journey in upgrading! I might come back and update it with additional nuggets of wisdom, but your own upgrade path could be different.
I highly recommend you read the following before you begin your upgrade so you’re familiar with other known issues:
The docs warn that you reconsider managing state integration yourself, citing that you could lose some optimizations. It’s good to manage state yourself if you have complex navigation or debugging, but upgrading is always a time to consider simplifying to the essential.
If you have any other “gotchas” please tweet them at me so I can add them in this post!