As a whole, React Native is an amazing platform. Using the React architecture seems like a perfect fit for building native applications, and as an added benefit, makes the process of developing more accessible for an abundance of developers.
Earlier in 2015, at their annual React.js conference, Facebook made an exciting announcement with the release of React Native: a platform bringing the brilliance of React JS to the process of developing native apps. For years web developers and designers have looked for a platform allowing them to use their web-based skills to create mobile apps, the question remains, is React Native the platform to bridge this gap? Furthermore, is it a game-changer in the landscape of platform architecture and development?
Similar to my previous React JS article, this article provides an overview of our experience using React Native, highlighting the good and the bad, and adding color to the questions posed above.
Before I drive into a more technical overview of React Native, let me go over some background info on the framework.
If you’re familiar with the core framework of React JS, React Native brings the same concepts of component abstraction, unidirectional data flow, and state and property management to native app development. React Native uses the same javascript architecture patterns to implement native mobile views and business logic, linking the provided React Native components to native platform specific components.
When React Native was initially released, it launched only supporting iOS; however, in September of this year, support for Android was announced.
The idea of using web-like technologies to create native apps has been done before, on several occasions. Unfortunately, most of these attempts fall short, as their performance is quite poor. Ultimately the experience delivered falls considerably short of a true native experience.
Unlike some of these other technologies, React Native implements a bit of javascript magic to make the compiling from javascript to native as performant as possible. Where these other platforms are typically wrapping markup and css inside a default iOS webview, and or mimicking HTML and CSS inside native iOS objects, React Native uses a multi-threaded approach to keep layout and performance heavy activities (like animations) as separated and thus smooth as possible.
Over the past few months we have had the chance to use React Native on a few client and internal projects and, all in all, I’m very pleased with the experience. A few hiccups here or there, sure, but aside from those, it was amazing to use the already elegant React framework to build something previously out of our repertoire.
When I was first jumping into React Native, I wasn’t sure how much React I’d actually be writing. Was React Native simply adding React inspired component-driven architecture to Swift? Was it borrowing a handful of React concepts into the XCode workflow? Nope, it’s literally utilizing React and plain vanilla javascript to build your app. 99% of the code you’ll be writing is javascript.
If you’re familiar with the concepts of React JS: component lifecycle methods, composing the DOM using components, etc., you’ll be very familiar with React Native.
Being that the platform is essentially javascript with some help from NPM, you’re able to use other javascript packages, also loaded from NPM. In my previous article on React JS, I mentioned using Backbone to help store and organize data. With React Native, I was able to use Backbone again, keeping the implementation nearly identical to the way I was building on a web-based React project.
Xcode provides Swift and Objective C developers with a plethora of components to build native apps. Many of these components have been built into React Native, and are immediately at your disposal when getting started.
Basic components like Images, ListViews, ScrollViews, Sliders, TabBars, etc. are able to be added into your app, using an easy to understand component-driven implementation. The full list is far too expansive to list here, but take a look for yourself.
Beyond basic components, various iOS APIs have been incorporated as well. AsyncStorage, CameraRoll, PushNotifications, Vibration, etc. All APIs the developer has access to when building their native apps.
In addition to the large amount of native components the RN team provides, the RN developer community is creating additional components available to developers.
Sites like React Components and React Parts contain dozens of additional components for React, implementing other iOS specific design patterns, or in some cases additional functionality. In our most recent React Native project, we used Mapbox’s React Native Component to create a custom stylized map in our app.
To provide aesthetics for the app, React Native utilizes a simplified version of CSS, to assist with styling your components. Most standard color, type, and layout style properties can be used in React Native, and the process is very familiar to a HTML/CSS workflow; albeit all of your styles need to be inlined within a components javascript file.
To provide positioning of components within the screen, React Native uses a slightly modified version of Flexbox, allowing the user to create a layout scaling between orientations and between device sizes. Yet another example of how smooth RN makes the transition from web to native.
As with most native app development, development and testing is done through the iOS simulator. React Native also provides Google Chrome integration, allowing developers to debug their app using Chrome’s web inspector tools. Errors, Logs, and Warnings are all able to be output into Chrome, again making things very web dev-like.
React Native also provides a mechanism to test your app on a local device. Simply change a few settings in the AppDelegate.m file and you’re ready to build your app and test it on your phone. Pretty seamless.
React Native is essentially a NPM package doing a bunch of javascript magic, linking the javascript in your application to the build process going on in XCode. In my experience on the projects we worked on, this link always felt very fragile.
When I was first setting up React Native on my machine, I ran into a handful of configuration issues and small bugs, which I needed to work through before being able to compile and run the app. Most of the bugs were only a few google searches away, but none the less, I wouldn’t call it a turn key solution for a junior dev.
During development I also ran into several issues with various XCode specific settings. To be fair, this was my first time working in XCode, and things like Build Phases, Image Assets, and Binary Linking were all new to me. However, a couple times I ran into a bug where the Github issues solution was "Just change your [insert arbitrary XCode setting], it worked for me!"
Lastly, as we neared the end of the project, I realized the version of NPM we were using was slightly outdated from the original release. After going through the upgrade steps React Native recommends, I was having issues getting my app to build. Because of our launch deadline, I was forced to rollback the upgrade. Again, this could have been due to my novice experience with XCode, but upgrading React Native felt a little undocumented and too cowboy for my preferences.
While React Native might have worked through some of the compilation and performance kinks frameworks like PhoneGap and RubyMotion suffer from, React Native does still have the downside that you’re working a layer away from Swift and Objective C. This means any updates made to iOS, or any of it’s native components or APIs, need to be migrated into their React Native counterpart.
On several occasions I was trying to implement functionality I saw was allowed by iOS using native components, however a React Native component wasn’t configured to handle what I was looking for. In some occasions this was for first-party React Native components, and other from third-party components.
These issues weren’t life or death to the experience of our app, but did require we rework some of our design implementation to work around the issues.
This last point might be a little picky of me, but the workflow required to build React Native apps gets a bit long winded when you’re trying to test and incorporate small adjustments here or there.
The process of getting React Native up and running is a bit complex:
When we were in the testing and bug fixing stage of development, we also needing to re-archive the project, upload to iTunes connect, and wait for it to be deployed on our individual devices. Any small change at that point was taking about 10 minutes to make live.
As a whole, React Native is an amazing platform. Using the React architecture seems like a perfect fit for building native applications, and as an added benefit, makes the process of developing more accessible for an abundance of developers.
That being said, I’m curious to know how many experienced iOS developers are using the framework. Do they find it easier to write apps normally, or does the added benefit of using React make the process of native development smoother?
I have heard from a few other developers—those using React on their marketing website, product, and iOS app—that they’ve been able to reuse a significant amount of code across their entire platform. I’m still not 100% sure the level of carry over, but the ability to swap components between platforms and products, seems like the future of native and web development.
I’m curious to learn about other who have used React Native and their big takeaways. What was your experience? Did you run into any major snags along the way? We’re you able to reuse code across platforms? Will you be using it in the future?
As always, don’t hesitate to reach out with any thoughts or feedback, and good luck!
Subscribe here to get our short and sweet monthly newsletter!