React Native: Upgrade Dos and Don’ts
While React Native is a great framework for cross platform development, the process to upgrade from one version to another is generally painful. If you created a new application this time last year, it was most likely running on version 0.56. Today the latest version is 0.60, and 0.61 is right around the corner. So, do you really need to update? And is it really that painful?
Why you need to update
We’ve already discussed sharing data components between React and React Native, but what do you do when it’s time for upgrading? There are two things that drive updating the React Native version in a project. The first is when you have to because of compatibility issues. React Native updates take some time, especially when you factor in a regression test for your application, but it’s hard to argue with the whole “update the React Native version or your app stops working.” Ideally that’s not a situation you run into, but it definitely happens. There’s been a handful of compatibility issues in the past year.
Google Play Store’s 64-bit requirement
Google is very interested in ensuring that all apps on its Play Store provide a 64-bit architecture. Earlier this year, Google announced that any app update submitted after August 1st 2019 would require 64-bit support. Unfortunately, React Native did not support builds targeting a 64-bit architecture on Android. We saw this supported added with version 0.59. If you are looking to release a new build on the Google Play Store today, you must run on 0.59 or later.
The AndroidX Debacle (0.60)
The Android ecosystem has historically relied on the Android Support Library (https://developer.android.com/topic/libraries/support-library/index). This library allows for the use of newer APIs on older versions of Android, or at least provides a graceful fallback. They have replaced the Android Support Library with another library, AndroidX. React Native did not play nice with AndroidX until 0.60. This became an issue because Google Play Services depends on the Android Support Library.
Many other libraries depend on Google Play Services for various features such as push notifications or maps. Google Play Services depends on the Android Support Library. When Google Play Services switched to AndroidX, a lot of React Native Android modules broke. These modules depend on Google Play Services, but do not specify the specific version that they require.
Fortunately, there is a way to work around this by modifying your project’s gradle file. Because of this, it does not force you to update React Native to get around the issue, but it certainly makes it easier. If you do decide to make the jump to a newer version of React Native and find native modules that are failing because they require the old support libraries, you can get around that. Running
will crawl your node_modules and update any Android files using old support libraries to use AndroidX instead. An easy way to run this automatically is to add a post-install script to your package.json:
`”postinstall": “npx jetify”`
Xcode 11 Support
iOS 13 is upon us, and with it comes Xcode 11. Apps compiled with Xcode 10 should work on iOS 13 just fine, but you cannot target iOS 13 devices and simulators for debugging without Xcode 11. Unfortunately, React Native did not play nice with Xcode 11 out the gate. The development teams addressed this issue in later releases of React Native 0.60. Your app may run fine on iOS 13 now, but it is important to update so you can target iOS 13 while debugging.
Related: How to Combine Top Tabs and Bottom Tabs into a Hamburger Menu
Why you want to update
The other reason to update is new features to take advantage of. These aren’t mandatory, but can make development much easier. Let’s look at some of these fun features introduced in the last year.
New in 0.60, Autolinking is an excellent new feature. Before 0.60, linking native modules could be difficult. Most native modules could be installed just by using the command:
`react-native link <package name>`
This command changes some native Android files and adds a reference to some iOS files in your Xcode project. Often, this just works, but that is not always the case.
On Android it’s usually easy to link your native module multiple times. There’s some protection to not link already-linked modules, but on Android this check fails often. If we link a native module more than once, the project won’t build. Fixing this requires manually editing the native files to remove the duplicated lines. Fixing this is usually easy, but is definitely annoying.
On iOS there’s a lot more that can go wrong. For a long time there was no package manager on iOS. Cocoapods is a popular third-party tool to fill the void of no manager package manager. Some native modules will have additional dependencies and recommend installing these through Cocoapods. The first time it does this, it creates a pod file for your project and lists the required dependencies there. The next time it links a native module, the CLI will detect that you have a pod file and link native files there. If those reference React, which they probably do, then an incredibly old version of React will be installed by Cocoapods which causes issues. At this point, your options are to link manually or to make modifications to your native project so that React will play nicely with Cocoapods.
Enter Autolinking. On Android, there’s no files to modify anymore. The build process will check the node_modules folder during build and include the code that it finds there. iOS works a bit differently. As of 0.60, React Native relies on Cocoapods now. Out of the box you will have a functioning podfile for dependencies to be added to. Running `pod install` will scan the node_modules folder for dependencies and link them automatically. On both platforms, the process is incredibly easy now.
Autolinking is not completely automatic though. Any extra steps that needed to be done outside of `react-native link` will still need to be done.
More features are added to React Native constantly. There are two new great additions coming in 0.61.
Live and Hot Reload are gone in 0.61, there is only Fast Refresh. The developers are so confident in the performance of Fast Refresh that the old Live Reload option is gone completely.
How do you update?
So now that you’re onboard for the update, how do go about doing it with the least amount of pain? There are two ways to go about it.
The simplest way is with the React Native CLI. Just run `react-native upgrade` and answer the prompts that follow. This is a great solution for projects that have little to no native code changes. If you have native changes, which you probably do, then the CLI is not that useful of a tool.
2. Upgrade Helper
Using the Upgrade Helper web tool is a manual process, but it is the best resource for React Native updates. It is a must if you have made native code changes. You just select your React Native version, select the React Native version you would like to upgrade to, and press the “Show me how to upgrade!” button. Review the changes displayed and apply them to your project. At the end you will have a working project on the version you targeted! This process can be tedious, especially if making a big jump such as <0.60 to >=0.60. However, it allows you to review changes line by line and make any adjustments when you encounter native code that you have modified.
Does your app need React Native re-platforming?
Senior Mobile Developer
Andrew is a Senior Mobile Developer focused on creating quality user experiences. He is a full stack developer with experience working on every piece of a mobile application from backend APIs to frontend UI. Andrew is passionate about creating high performing native applications. He also has the distinguished mantle of being the longest-tenured developer at Shockoe.