Although it leverages core web technology, React Native does not use webviews for UI; instead it uses real native views. React Native isn’t limited to building views: many native APIs can be leveraged by React Native, such as networking, camera access, and push notifications. Despite React Native still being in beta, Facebook has used it in Facebook Groups, Facebook Ads Manager, and their recently open sourced F8 app.
When you might want to consider working with React Native:
Things to be wary of:
As a rapidly growing product development company, Connected has a lot of moving parts: we need to manage clients, contracts, projects, and employees. Instead of inputting this information into a bloated and unwieldy spreadsheet, we decided take a more elegant approach by building an internal web application; we call it Allocations. The main features of Allocations are as follows: list current projects, display the contract status of each project, indicate who is managing each project, and indicate which engineers are working on each project.
We used React Native to build a native iOS and Android app for Allocations, and we would like to pass on what we’ve learned to you!
In contrast, native development on both iOS and Android have been notorious for slower compilation time compared to other forms of development, especially with more complex projects. In order to add new UI elements or pixel pushing in general, we would have to wait for the entire project to compile and run every time we want to see our changes reflected on an actual device.
Another unique tool React Native developers should take advantage of is the Inspector Tool. This tool allows developers to click on view components to highlight and inspect its current style properties (eg. margin, padding, size, color). Adjusting each UI component in our Allocations app to match the mocks was pretty simple with this tool as it provides a complete analysis of each component’s properties as well as the entire view’s hierarchy. For example, we can immediately tell whether our “TouchableHighlight” has a 15dp margin or “ProjectListCell” has a 15dp padding with the Inspector Tool as you can see in the screenshot above. With this information we’re able to easily analyze and debug each view with knowledge of its exact properties.
Share modules to reduce fragmentation
Through our experiences with native modules, we learned to keep the style consistent as much as possible to avoid fragmentation throughout the app. One good example was when we decided to use both Navigator and NavigatorIOS for navigation in a single app. At first it seemed like a viable choice because NavigatorIOS provides the native toolbar and provides native iOS navigation animations as it leverages the UINavigationController class. However as the app became more and more complex, we found that we’d been generating an unnecessary amount of duplicate code while handling navigation for both platforms. In the end we decided to go with just pure Navigator because it gives us more flexibility on exactly how we handle navigation including how we pass properties and define the animations between pages. This way we’d only have to write the navigation code once for both platforms.
Otherwise you’ll have to manage multiple pairs of native components in different ways with mostly similar functionality. You would likely be making platform checks via if-statements all over your codebase, which we all know is a pain to maintain.
Avoid poor performance with lists
There are some performance pitfalls with React Native. One notable one we found for iOS is that the ListView component is not built with UICollectionView. Instead of leveraging UICollectionView’s ability to reuse view cells as the user scrolls down the list, React Native renders each cell individually without deallocating cells that have been scrolled passed. This means that you may get framerate drops if your cells are complex and you’re scrolling quickly (since they are continuously being re-rendered) and your memory usage will steadily increase as you scroll. React Native’s ListView has some properties you can tweak to circumvent the framerate issue, such as pageSize and scrollRenderAheadDistance. Something else to try is turning off development mode when you run the app. We had some performance issues on the main project list of Allocations which disappeared when we deactivated React Native’s development mode.
Check for updates often
Since React Native is still a relatively new platform and still in its beta stage, you should keep up to date with their changes. Facebook is not only rapidly adding new features, but also makes a lot of changes to current features. For example, importing static images prior to version 0.14 would require images to be stored in their respective project’s resource folders. In order to import the images you would have to do a require without identifying the location of the images (eg. require(image!appIcon)). However, Facebook decided to change image management to prevent having to manage two image sets and allow the developer to decide where the images are held instead by specifying the relative paths (eg. require(./images/appIcon)). As a result all of our image imports were no longer valid after the upgrade to 0.14, so it was a good lesson to thoroughly read through their changelogs before deciding to perform the update.
If you don’t keep up to date with the current React Native version, you could easily be writing broken or deprecated code throughout your app which would become gradually more difficult to refactor. Facebook usually provides warnings regarding potential changes to their APIs at least one release ahead of time to give developers the time to refactor their code. There are plenty of improvements and new feature sets in each release as well. Make sure you prioritize your work so that you’re not reinventing the wheel for features that will eventually be available in a near future release.
React Native is already mature enough for production: just look at Facebook’s React Native showcase or our Allocations app for proof. What’s exciting is that Facebook seems serious about fully developing React Native into a robust alternative for mobile development. Since React Native is open source, we can expect significant community contributions as well. Here are a few recent developments in the React Native scene: