React Native has been around for a while. When Android support was released (about a year after iOS was released), I used it professionally. I decided to invest time in cross-platform development. I had been an iOS developer for 6 years when I discovered React Native, and not just a Mac OS X developer.

I developed four medium-sized (10,000-20,000 lines of code excluding dependencies) projects for my clients in both the App Store and The Play Store. I also oversaw and contributed to a much larger project containing over 50,000 lines of code written in React Native (in addition to Native code) that is now being deployed in production and running smoothly. I’ve accumulated enough experience to figure out what’s great about React (and React Native), and where it’s not — and how to extend it.

Note: I know some of you are pointing to Flutter while reading this article. Since its maturity is nowhere near that of its competitors, I haven’t considered it.

As of this writing, React Native’s current stable release is 0.57, with 0.58RC coming.

Here’s what I think:

React Native’s most widely known and least important feature

React Native is best known for being cross-platform, but that’s not what caught my attention. The most important feature of React Native is that it uses React, so it supports a generic declarative layout. Cross-platform support comes in second. As an iOS developer, I’ve been trying to design the user interface in a way that isn’t intuitive; Automatic layout system.

If your system is highly dynamic and on-screen elements (such as drawers and animations) depend on each other, Apple’s Autolayout is the best way to manage on-screen content. However, this is not the case for most Android and iOS apps. Most Android and iOS applications use the standard elements we’re used to seeing: text, buttons, lists, generic views, and images laid out in the most Web-like way possible.

In the time between the invention of AutoLayout, the FlexBox system was invented and used as a de facto standard for putting things on the screen. In addition to standard Web use, there are layout systems designed to exploit FlexBox principles for native development:

There are more interface libraries – these are just a few that are well known. One thing they all have in common is a declarative user interface approach.

Declarative user interfaces:

Declarative user interfaces for mobile development were created to address the problems of traditional layout systems. You declare your intentions, and the system generates results based on them.

Declarative user interfaces address few of the following mobile development challenges:

Componentization. IOS uses ViewControllers in ViewControllers and looks at them in view. Android uses Fragments. Both have XML interface declarations, and both allow runtime view instantiation and editing. When it comes to breaking them down to smaller or reusing them, you’re doing a little refactoring. In declarative user interfaces, this capability is already available by default.

Developer productivity. The declarative user interface is responsible for resizing components for you. Take a look at this code (React Native example) :

class TestTextLabel extends React.Component {
  render() {
    return( <view> <text>This is a small text</text> <text>{this}</text> </view> ); }}Copy the code

The above code renders a Component that contains only two text components. Pay attention to this. Props. SampleText. What happens if this variable is too long (for example, -10000 characters long)? The result will be that the component will be resized to fit the entire text. If the text reaches the end of the allowed space (screen, let’s say), then the view will be clipped and the user will not be able to see the entire text. You need a scroll view.

class TestTextLabel extends React.Component {
  render() {
    return( <ScrollView style={{flex : 1}}> <Text>This is a small text</Text> <Text>{this}</Text> </ScrollView> ); }}Copy the code

The only change is the addition of the <ScrollView> element. If you’re on iOS, this takes a lot more work.

Collaboration – Git management throughout. Every declarative UI I’ve seen is better.

On iOS and Android, if you have big chunks of UI, you’re doing it wrong. However, large XML files are unavoidable in most cases (for iOS: XIBs are actually XML files). Their changes don’t mean anything to the code reviewer (or you) – if you don’t agree with a previous version (your or another developer’s changes) to remain intact, it’s nearly impossible to pull requests.

With React and other declarative UI libraries, these problems are largely minimized because the layout is actual code — code that you can update, delete, merge, differentiate, and do all the things you normally do with any other part of the software.

The key is to understand what “performance” really is

You may need to become a mobile developer to grasp performance concepts and manage efficient memory and processor usage.

The React Native concept can be used by Web developers without knowledge of Native and is only suitable for small projects. Once your application starts to grow and Redux store computing starts to take a toll on your application’s performance, you’ll need to understand how the Native side works to understand why this is happening. You also need to be aware that the Redux Store in React Native causes a rerendering that is not exactly the same as what happens in the DOM. This is especially true for components coming from the Native side of the application.

Also, re-rendering the application’s components on React Native can become expensive. Because React Native uses a bridge, any instructions you provide inside the Render () function will be passed from JavascriptCore to Java/Objective C ++. The Native end will take the Render () instructions given in the JSX tag and convert them into their native counterparts, such as views, labels, and images. If done hundreds of times per second, that translation requires a significant amount of CPU time.

In the performance department, it seems React Native is one of the better cross-platform solutions. However, there are still performance issues with React Native in some key areas.

One such example is large data sets (and lists). In the case of large list and grid views, Android and iOS offer an excellent and extremely flexible solution – reclaim views. Imagine rendering only the cells that are displayed at any given time when using a large list view (iOS/Android). The other cells are marked reusable so that they can be reused when new cells are about to be displayed. When changing a data set, the operating system simply updates the cells that are displayed.

React Native provides VirtualizedLists and their derivatives (flatLists and sectionLists) for large data sets. However, even this leaves much to be desired. There are performance costs, especially when rendering complex components in SectionList and trying to update large data sets of over 100 objects. Update mechanisms slow down low-end or mid-range mobile devices.

To address this issue, I’ve switched from Redux to MobX, which provides more predictable updates to my components. Also, in the case of large lists, MobX can update specific cells without rerendering the entire list. Often this can also be done with Redux, but you need to override componentShouldUpdate () and write more boilerplate files to avoid unnecessary rerendering. While copying the remaining variables to the new state, your Reducer still does some unnecessary work.

Bottom line: Be careful. The fact that you use React Native means that achieving the best performance from your application requires familiarity with React best practices and Native practices.

It is important to understand the JS runtime and how it affects you.

You can debug React Native by sending debugging information to Chrome’s bridge. This means that the process of running the actual code on the device is different from the process of debugging the code.

React Native on Android and iOS executes Javascript using JavascriptCore. However, the debugging tool runs on V8 (Chrome). To make the system more decentralized, as of this writing, React Native uses Apple’S Javascript Core on iOS, while on Android, They’re using a 3 year old build script for JS Core (since Android doesn’t provide any JS runtime) and a box like iOS that Facebook has to build themselves). This results in a lack of JS features such as proxy object support and 64-bit support on Android. So if you want to use MobX 5+ he/she is out of luck unless you use an upgraded Javascript runtime (read on to learn how to do this).

Runtime differences often result in errors that can only be reproduced in production. Even worse, some things become unrecognizable.

For example, when it comes to React Native, the best solution for moving databases is Realm. However, this happens when you go into debug mode: https:// github.com/realm/realm-js/issues/491. The folks at Realm have explained why this is the case – but most importantly, the React Native debug architecture must be improved if we want a more stable debug solution. The good news is THAT I’ve been using the Haul as my bundle, which allows me to debug directly from my iOS devices without going through Chrome Dev Tools (unfortunately, you need Mac, iOS emulator and Safari).

Please note that people at Facebook are already aware of this problem and they are redesigning the React Native core so that the Native and React Native parts share the same memory. Once this is done, you may be able to debug directly on the device’s JavaScript runtime. React Native Fabric (UI-Layer Re-architecture).

Not only that, the React Native community now provides JS Android build scripts that allow you to build newer versions of JavascriptCore and embed them in React Native applications. This puts Android’s React Native Javascript functionality on par with iOS, and paves the way for the addition of 64-bit support for React Native running on Android.

React Native is great for in-app navigation

Have you developed mobile applications with authentication? What happens if the user receives a push notification and has to go through the login screen first, and can only see the push notification content screen after logging in? Or, what if you are currently deeply nested in your application and want to jump to a completely different area in another part of your application in response to user actions?

Problems like Native can be solved in Native with some effort. With React Navigation, they’re not even a problem. Deep links with related routes and navigational jumps feel natural and smooth. There are other Navigation libraries, but React Navigation is considered the de facto standard. You should give it a try. This is the way React Native is better than iOS and Android.

React Native is not a silver bullet

As with any other technology, you need to understand what it is and what it is before you invest. The following

  • Is a non-exhaustive list of what RN is good at:
  • Content-driven applications
  • An application with a Web-like UI.
  • Cross-platform applications may or may not require fast time-to-market.

Here’s a non-exhaustive list of where RN is far from perfect:

  • Applications with huge lists
  • Media-driven applications do not require layouts (e.g. simple/small games, animation, video processing) or screen-to-screen transitions.
  • CPU intensive tasks.

Indeed, for things React can’t do, you can write everything you need in Native and then call the corresponding code from React Native. But that means you need to write code once for each platform (iOS, Android), and then write additional code for the Javascript interface.

React Native’s internal components are currently undergoing a major refactoring, so RN can perform more operations synchronously in parallel so that it can share common code with Native. Facebook. Making. IO/react – nativ… – Before you do that, you should do some research before deciding whether to use it.

conclusion

React Native is a well thought-out and well-developed platform. It opens up the NodeJS world for your application and lets you program in one of the best layout systems. It also provides you with a good bridge with Native aspects so that you can make the most of both worlds.

However, it also falls into another strange category – you need one or three teams to develop your app! At some point, you’ll need some iOS and Android developers to build components that React Native doesn’t have by default. Once your team starts to grow, you’ll have to decide whether to make your application 100% Native. So, no matter how much React Native you choose for your next project, it’s a question of how much Native code (Java/Kotlin/Swift/ObjC) you need to have.

My personal tip: If you realize you need 3 teams to develop three aspects of an app (one iOS team, one Android team, and one React team) then you should be able to always use Native iOS and Android and skip React Native. You will save time and money by maintaining only two code bases instead of developing three.

However, if you have a small team of skilled developers and want to build a content application or something like that, React Native is a great choice.