If you are reading this article, you probably fit one of the two groups:
You are a native iOS or Android developer thinking about transitioning to RN, or
You are already familiar with RN, but a friend, who is a native iOS/Android dev, asked you for some advice on how to learn RN.
In both cases, you are welcome and this article is for you!
Half a year ago I had nothing in common with JS, but I successfully made the transition. Now, I can share some hints that could save you from several mistakes I made. This article doesn’t go deeply into details, but rather is a brief and broad introduction to RN. I also provide links to more detailed resources.
Just an RN example of a “Hello World” app
First, let me give you some background about why I decided to change my technology of choice regarding mobile app development. I have experience with both native development (iOS and Android) as well as with cross-platform development using Xamarin and Unity. I liked all these technologies, but I was looking for something fresh for app development, something that would allow me to combine what I already knew. I believed that cross-platform development for sure was the way to go. I chose to learn about React Native.
When I first used it, I was totally confused. It was not like anything I used before. Different language, different environments, a paradigm shift. It took me some time to get used to the new technology, but now I’m sure I made the right choice to transition to RN.
What is React Native
To us, native developers, it’s especially important to understand what Native stands for in React Native. It represents rendering of native views, which is a good thing. A bad thing is that it still runs not-so-native JS, instead of faster native code. Fortunately, usually it’s hard to spot a performance difference.
If you want to dig into details, we compared two identical apps, one written in Swift and the other one with RN, and wrote a story about it.
How to start
When I was taking my first steps in React Native I have read many guides and I can especially recommend these two:
- The official React Native “Getting Started” guide by Facebook is an awesome resource for first steps. It’s up-to-date and well-organized. At the very beginning of this guide you have to choose a toolchain: React Native CLI or Expo. However, I advise you to not use Expo in the long run. Expo is easier at the very beginning but becomes troublesome later, as not all dependencies and native modules work well with it. You, as a native developer, should think about the possibility of reusing what you already know from the native world and not limit your options with Expo. Fortunately, you can always “eject” your code from Expo into a pure RN project that will work with the standard React Native CLI. When using React Native CLI you will learn more and your project will not suffer from Expo’s limitations.
If you are craving more knowledge, we have also written up a broader selection of tools and resources that were considered the most useful by my colleagues. It’s available in this Codestories blog post.
You can write RN apps using any text editor or IDE you like. Currently the most popular tool among RN devs is Visual Studio Code. It’s highly customizable and gives access to lots of extensions. The other popular IDE worth trying is Deco. Just use whatever you feel fits you better.
When it comes to debugging you can just use your browser (Chrome DevTools), but there are more powerful alternatives available. One of them is React Native Debugger, which runs as a standalone app. Beside a must-have debugger console, it gives you the tools to easily analyze the stored state of the app or view components’ hierarchy.
While it’s an awesome debugger that often saves a lot of time, it unfortunately has a small downside: it awfully slows down the running app. My hint for you is to use it when you really have to debug something non-trivial, otherwise use the default debugger in the browser.
We have published a blogpost that goes more into details of debugging. There, you can read about another powerful tool – Reactotron. It has a slightly different approach to debugging and runs faster than React Native Debugger.
In case of the most complex issues, you can still profile and debug using Xcode and Android Studio you are already familiar with. They are the best when you need to profile performance or solve weird rendering issues.
One of the first steps in a new RN project will be choosing a navigation library. The choice is not simple, as there is no official RN navigation and many libraries are competing. These are the two I think are the most commonly used:
- The most popular library is probably react-navigation. It has an opinion of being relatively easy but not the most performant, because it doesn’t display native navigation components.
- Another popular one is react-native-navigation (created by wix). If you have a native background you should definitely try this library as it’s more customizable and uses truly native navigation components.
Calling native code and performance
Basically, in RN apps code can be split into two worlds: JS and Native. Yes, obviously you can call native code from JS. React Native, through the Bridge, exposes JS interfaces to the native platform’s API. This means that the app can use native features, such as the camera, Bluetooth, and GPS.
Separately, code in each one of these JS and Native worlds runs fairly quickly, but sometimes there is a need for communication between them, which unfortunately is slow. The Bridge works as a translator between the two worlds.
Diagram illustrating the Bridge between JS and native code
Knowing this you should try to limit the number of calls through bridge to a minimum. The official documentation (iOS, Android) is also a fairly good resource explaining the details of native modules.
Usually you don’t have to go very deep into the native world, because this unique native feature you need is probably already implemented by some package in npm. As I said previously, the JS and React Native communities are huge and active so chances are it’s already done.
At the very beginning of my adventure with RN it was hard for me to understand the Component lifecycle. It’s probably because I expected it to look similar to native lifecycles. Well, as you guessed, it’s pretty different. In fact, in RN our views have two lifecycles: the native lifecycle of UIViewController on iOS or Activity on Android wraps the Component lifecycle.
Diagram presenting the phases of the RN Component lifecycle inside native lifecycles.
Let’s continue looking at the examples of UIViewController on iOS and Activity on Android. Their lifecycles span over their lives similarly to how a movie would go from the very beginning to the end. This is different from Component, whose Updating phase lifecycle looks more a single frame from a movie.
Diagram showing the detailed lifecycle of React.Component (source)
The Mounting phase of Component is done only once per its wrapping native view’s lifespan. After the componentDidMount call we know that the Component is bound to a native view and is first rendered using the initial props and state. Here are some links to the official docs explaining props and state.
The next phase is Updating. This is the phase I compared to a single movie frame. Component runs through this phase every single time it has received new props or its state has changed, and these are the only conditions when it can be re-rendered. After each update a new movie frame is rendered.
In the Unmounting phase after the componentWillUnmount call we know that Component will soon be detached from the native view.
It’s worth noting that when learning you will probably find resources that present the legacy lifecycle of Component. Remember that componentWillMount, componentWillReceiveProps and componentWillUpdate are considered obsolete since React v16.3.0 (released on 29 Mar 2018).
For me, the most apparent difference between developing a completely native app and an RN app was the totally different architecture. Native iOS and Android projects are usually written using one of the popular architectural patterns: Model-View-Something, VIPER or similar.
The architectural patterns that are the most commonly used in native development usually just do not fit the React.Component lifecycle. This is why usage of state containers as Redux is so popular in RN.
Worth noting that in native worlds the MVI paradigm is getting more and more attention. In fact, MVI implements the Flux concept, so it’s quite similar to most of RN apps architecture.
Diagram illustrating the most popular architecture for RN apps - Redux
As RN is based on React.js it also uses a lot of its tools. The most notable part is the usage of state management libraries, from which the most popular one is Redux. It’s possible to write React apps without it, but if you want to become an RN dev you really should understand Redux. Read this article if you want a detailed answer why Redux is that beneficial for a RN app.
The RN environment may seem totally different from what you know from native iOS or Android, but I hope that with this guide the transition will be easier. Your career and satisfaction can benefit a lot from learning something new, especially if you are bored with your current technology or just looking for a new challenge.
Did you find this article helpful? I would be extremely happy if you liked or shared it with friends.
What was different in RN from what you initially expected? Do you want us to describe something in detail? Feel invited to write your thoughts in the comments section.
Good luck with your React Native adventure! I’m sure you will like it!