I just came across an old answer I posted in Quora on August 2015 about the future of iOS development. Roughly a year and a half has passed, and things haven’t changed too much to be fair. One of the key points I mentioned in my answer is the ability to speed up the “try” cycle so you don’t have to wait to see your changes. My original bet was on the Apple side, but so far it hasn’t happened.
The app has some simple animations and some native-side code to hold the list of todos. My intention was to explore how the communication with some custom native-side components worked and find out how hard it is to get a simple UI that feels native. The main question I wanted to answer was if React Native does in fact bring the web development cycle to the mobile world.
I wrote a native component for iOS and another one for Android. Both do the same, handle the list of todos (add, delete and toggle the “complete” state). The original intention was to handle the list in the user’s calendar, so adding a todo should add a reminder to the user’s calendar, but I ended up verifying my hypothesis about React Native way before reaching that feature so it fell out of scope.
Next, I list some of the things I found particularly grateful to have during the development.
Coming from iOS I was amazed with Flexbox and how well it played in the mobile environment. I was able to perform simple translation + resize animations without any code on both platforms and spent very little time thinking about layout. This is a big contrast to how this is handled in native iOS (fixed position + autoresizing mask + auto layout + view stacks).
XMLHttpRequest), that also use promises.
- arrow functions to define lambdas
- destructuring to access object fields with things like
let [a, b] = someArray
- and many others
Also, if you bootstrap your project with
flow-bin tool to check that your types match. This fits nicely with how React allows you to specify types for the properties of your components and make your React code type safe which is great.
Platform specific components
React Native runtime supports a nomenclature to specify which definition of a component it should use based on the platform where the code is running. So if you have a
NiceWidget component that looks different depending on the current platform, you can split the logic in two files
NiceWidget.android.js and at the point of use make reference to the name without any extension:
let component = require('./NiceWidget')
I really can’t find too many downsides in the technology for now, but I’m pretty sure this is a clear signal of my lake of experience. Anyway, these are some observations that can be seen as downsides but really depends of the context.
You also have to be careful about what packages you install and watch the versions of everything. React ecosystem moves fast and things get old quickly, so you need to take the versioning of everything in your project with caution. Also moving to a new version of React Native could be complicated so reserve some time for that if you need to do it.
For Android you need to construct a special data type
WritableNativeMap that holds the type information for each value you put in. Also declaring a native component needs much more effort than for iOS. In iOS you just add a class to the project; for Android you need to create a class that implements the
ReactPackage protocol to load your new component and then pass an instance of that class to your main activity.
Objective-C vs Swift
For my TODO app I picked Objective-C (ObjC for short) over Swift for a variety of reasons. First and foremost, React Native for iOS is written in ObjC and relies on the ObjC runtime to load and interact with the native components you write. For a Swift class that means you have to:
* tag your class and all the methods you want to make public to the React app with
* declare a private ObjC class (private means only a .m file) that mirrors the Swift class and calls some React Native macros to make your Swift class accessible to React
* add a bridge header file to give Swift access to all React symbols you need. Because all those are written in ObjC.
Also I used
react-native init command to bootstrap my project and for iOS it generated an ObjC project so I was half way into ObjC from the very beginning. All the documentation and examples in the React Native site specific to iOS assume you are using ObjC, they don’t even mention Swift.
Given all the above, you have to think twice about using Swift with React Native. I have been working on Swift for a couple of years and in ObjC for a couple more, so for me it isn’t worth the effort. Maybe if the native component needed more code I would consider it.
Regardless of the fact that React and React Native are the same framework, there are some difference between them. First the components are not the same, you can’t use
p tags because you are no longer rendering to the DOM. That means that if you are an experienced React developer you still need to learn what components are available and, more importantly, how a screen should be split and what components you put in. That’s pure mobile development experience and knowledge of the underlaying SDK. There are some generic components that work for both platforms but there are cases in which the proposed UI doesn’t match one of the platforms, so you need to use a platform-specific component.
By far where React Native shines is in bringing the web workflow to the mobile development without ending with a full web app running on your phone. During the development of my TODO app, I was running the simulators for Android and iOS at the same time and just needed to hit a refresh shortcut to see my changes. No need for any IDE or compile - deploy - run cycle. That single feature by itself adds enough value to at least give React Native a try.
If on top of that you add the multi-platform capabilities and the fact that any web developer with minimal experience in React (I believe at least 90% of the web developers meet that condition) can write native-feeling mobile apps with little training, I think that React Native can become the way to go for almost any mobile app, at least at the early stage.