About two month ago, I started making a React Native app “PyConTW 17” for the biggest annual Python conference in Taiwan (PyCon Taiwan). The app is quite simple, but still took some efforts for me to build. As a complete React newbie, I would like to share some of my thoughts about React Native.
(written on 2017-07-30, based on React Native 0.44.2)
Disclaimer: I am a junior iOS developer (about 1 year experience) without any computer science degree. This article is based on my 2 weeks React Native experience developing “PyConTW 17” and React knowledge gained from my job recently.
What I’ve done
Before sharing my point of view, let’s learn what features are included in this conference app:
- A user could view all event/talk information of the whole conference.
- A user could save some favorite events for quick access (saved locally).
- A user could filter events by pre-defined tags of category.
- Events would update automatically if any data in database changes.
As an iOS developer, you may feel familiar with these requirements. The app may be just a tabbar-based app with some customized table view to display contents. No database. No synchronization for user-generated data. Our React Native version app share with this basic anatomy mentioned above. Therefore, the UI architecture only contains some views such as list views, detail views of event/speaker, and the main app container. That’s all in this app.
The good part
This project seems to only contain trivial implementation details from an veteran iOS developer’s perspective. What if you need to target at both Android and iOS in one week? Learning Android development from scratch may not be suitable with an approaching deadline, and the separation of codebase may be prone to maintenance issues in the long run. To achieve the goal, you could choose React Native in order to wrap the core logic into one codebase. No more switches between Android Studio and Xcode. React Native would give us a truly native app. That’s why React Native hypes.
Faster development iteration
We are all tired of write-compile-debug iteration for our daily mobile app development. With the growth of the bundle size, it would take more time to build our app (especially in Swift). React Native uses some tricks like Hot and Live Reloading to refresh your simulator/emulator instantly without recompilation. That’s really an incredible time saver.
Moreover, if you choose Create React Native App as the scaffolding tool, you can gain benefits from Expo platform to test your app in real devices without any wired connection. What you need to do is scanning the QR code and coding. This is a huge leap from traditional mobile native development cycle.
Did you remember the last time using the View Hierarchy Debugger in Xcode? This tool is very awesome for visually debugging, but sometime it’s quite laggy with complicated views hierarchy (improved in Xcode 8), and that leads to frustration. The solution React Native providing is a web-browser-like
inspector for us to inspect elements on simulators. With the inspector, you can see box model, styles and even inheritance hierarchy of the selected component without long wait for the rainbow ball rotating. Additional, React Native also has a performance panel to help you achieve 60 FPS animations.
If you need more advanced debug tools, there is also a remote debugging plugin available. You can download it from Chrome Web Store or Firefox Add-ons. This debugger allows inspection of React component instances, and you can also see logs from browser console.
There are still lots of tools that did not cover in this article. Either tools offered by Facebook or contribute by communities (like Redux Devtools) are convenient for daily use. Feel free from escaping Xcode!
To be honest, Xcode provides plenty of excellent debugging and profiling tools which are greater than those browsers have. However, they are not easy to start with, and every iOS developer I met seldom uses them.
Generator. However, due to the diversity of browser ecosystem, if one wants to use new features to support most browser vendors, it will need to add some polyfills or transpile all code to the target version. However, the setup procedure of build environment for transpilation is annoying to some extent.
In React Native development, this is no longer a problem. All we need are done by a scaffolding tool called
async/await syntax to avoid callback hell, and even use the new
fetch Web API for HTTP requests. In comparison of old web-based hybrid technology such as Cordova, React Native eliminates the scary setup process and brings all pleasant stuff to live!
Another sweet point of React Native is the dependency management. CocoaPods is de facto dependency manager for Cocoa development, yet it is written in Ruby that increases costs to learn. Nowadays we get Carthage which is written in pure Swift, though it still has some issues as dependencies being more complex and nested. No one want drag all dependencies of 3rd module manually.
As for React Native, we can use Npm (or Yarn I recommended), one the best dependency management and ecosystem in the world. Npm reduces the painful workspace regeneration and sharing issue with CocoaPods, as well as manages dependencies with nested resolution to avoid incorrect versioning. Though the whole packages may be a little bit large, it may not be a problem for a mobile app. After all, the connection status on the internet is more strict than native app. We should be content that we do not need to download all resources on every single launch.
CoreGraphics to accomplish).
Other developers coming from React community bring more new web development concepts to mobile land. For instance, unidirectional data flow, state management, component-based architecture, router patterns and many others. These concepts also have influenced back on pure native development, and invoke the reconsideration of traditional MVC/MVP/MVVM architecture. More and more talks discuss about view purification and state centralization. Some enthusiasts even started to develop a new state management module called ReSwift, which is inspired by Redux.
The benefit of these abstractions is not only full of cool jargons but predictable, making views become testable. The most important impact on native development in my opinion is the concept of predictable unit tests, which is absent in traditional MVC architecture.
The pain points
One codebase cannot rule them all
If you have read the official React Native website thoroughly, you will notice that the slogan of React Native is “Learn once, write anywhere” instead of “run anywhere”. One can realize that React Native does not aim to be shareable between different platforms. Actually, Facebook suggests that developers should design different components for different platforms to match platform-specified user experience. For example, an Android app may not need an back button for navigations because each Android device has a physical back button.
Another issue is related to platform differences. Not all API on iOS could meet a compatible API on Android. For examples,
shadowProps have no effect on Android yet Android has another
elevation style to generate a shadow-like visual effect. We may also face on some bug in old buggy webview of iOS like not calling
WebView#onLoadEnd after loaded. When it comes to build system, you may overwhelm by diverse toolsets for each platform. For me, I must learn groovy to write some gradle scripts which only read
keystore property for app signing and submission. How painful!
As an iOS developer, if there is no any React Native module that meets your needs, you need to tell your boss to recruit a real Android man for help, or pay you double to learn the whole new Android development stack.
Steep learning curve
As a traditional mobile app developer, you are familiar with object-oriented programming. Factory pattern, adapter pattern appear all of your daily life. What if someone told you that your function is not pure enough and suggest to use monad to wrap your API? These are all functional programming buzz words. Despite of flexibility of React Native, the Thinking in React concept makes React fit for functional programming paradigm. Most of the open source libraries built around React ecosystem conform to functional programming pattern. If you determine to adopt React Native into your development stack, it may spend additional efforts to learn with all those jargons. From a manager’s perspective, it is hard to recruit a well trained programmer equipped with functional programming skills (at least in Taiwan).
React Native uses
On Cocoa, we have the wonderful Grand Central Dispatch (
Dispatch framework in Swift 3), which abstracts thread management for us to do concurrent jobs. In React Native, if we want to manage real threads on our own, the only way is leaking abstractions. We need to write a native module creating another
Is React Native worth learning?
The short answer is: yes.
The long answer is: definitely yes for your next application. Learning React Native can leverage your knowledge to another level. Those impressive, promising concepts will sharpen your skills and bring great ideas to your software development knowledge. If you are still concerning about the cost of switch to React Native, here are some scenarios for you to choose React Native over native platform:
- Need to build this app within a short period of time.
- Single purpose app like “PyConTW 17” is most suitable.
- Not heavily rely on native API (sorry to HealthKit, ARKit and SiriKit).
- User interface is relative simple.
- Have teammate with strong native experience (we need both Android and iOS).
- Your team applies Hype Driven Development.
After all, everything in life is a trade off. Just ship your code and enjoy the evolving mobile app development world!