Why You Should Consider React Native For Your Mobile App

About The Author

Clayton Anderson is a partner at The BHW Group in Austin, TX. Outside of work, he is a total music nerd, and enjoys reading, Belgian beers, and playing board … More about Clayton ↬

Email Newsletter

Weekly tips on front-end & UX.
Trusted by 200,000+ folks.

React has proved tremendously successful, both on Clayton Anderson’s own projects, and with many others around the web, including large companies like Netflix. And now with React Native, the framework has been brought to mobile. React Native is a great option for creating performant iOS and Android apps that feel at home on their respective platforms. In this article, Clayton will explain why he thinks you should consider using React Native, by providing an overview of the framework and what he believes to be its best features.

Like many others, I was initially skeptical of Facebook and Instagram’s React. Initial demos of React’s JavaScript language extension, JSX, made many developers uneasy. For years we had worked to separate HTML and JavaScript, but React seemed to combine them. Many also questioned the need for yet another client-side library in an ocean full of them.

react native

As it turns out, React has proved tremendously successful, both on my own projects, and with many others around the web, including large companies like Netflix. And now with React Native, the framework has been brought to mobile. React Native is a great option for creating performant iOS and Android apps that feel at home on their respective platforms, all while building on any previous web development experience.

This article will explain why I think you should consider using React Native, by providing an overview of the framework and what I believe to be its best features.

React Overview

Described by its creators as “A JavaScript library for building user interfaces”, React focuses on the view portion of your application. In more concrete terms, this means that when writing a React Native app, your view code will consist of writing React components, which are small pieces of code that describe how a portion of your app should look based on some set of input data. Let’s look at a small example component which can be used to display a simple button. (I am omitting styles for the sake of clarity.)


const Button = React.createClass({
    propTypes: {
        onPress: React.PropTypes.func.isRequired,
        text: React.PropTypes.string.isRequired,
    },

    render() {
        return (
            <TouchableOpacity onPress={this.props.onPress} style={...}>
                <Text style={...}>{this.props.text}</Text>
            </TouchableOpacity>
        );
    }
});

This Button component has two pieces of input data: onPress, which is a callback function for when the button is pressed; and text, which is the string to display inside the button. The XML-like structure you see returned by the render function is called JSX, which is syntactic sugar for React function calls. And TouchableOpacity and Text are existing components that are included with React Native. Now that this Button component has been created, it can be used many times throughout the application, with consistent behavior and styling.

While this is a simple example, it demonstrates how a React app is built, piece by piece. Continuing in this manner, you can create components that represent increasing layers of abstraction. For example, you might create a ButtonGroup component that contains several connected buttons. And building on top of that, you can write components that represent entire screens. Even as your app gets significantly larger, components remain understandable and manageably sized at each level.

Truly Native

Most mobile apps built with JavaScript use Cordova, or a framework built on top of it, such as the popular Ionic or Sencha Touch. With Cordova, you have the ability to make calls to native APIs, but the bulk of your app will be HTML and JavaScript inside a WebView. While you can approximate native components – and it is certainly possible to build a great UI with HTML and JS – no Cordova app will match the look and feel of a real native app. The little things - like scrolling acceleration, keyboard behavior, and navigation - all add up and can create frustrating experiences for your customers when they don’t behave as expected.

Although you still write JavaScript with React Native, the components you define will end up rendering as native platform widgets. If you are familiar with React for the web, you’ll feel right at home. And if you have written apps in Java or Objective-C, you’ll immediately recognize many of React Native’s components.

React’s best feature when it originally launched for the web was making your app’s view layer a pure output of state. As a developer, this means that instead of imperatively making changes to view components (for example, programmatically altering the text or color of a button by calling a function on it), you simply define what your view should look like based on input data, and React intelligently makes the changes for you when the state changes.

This shift in thinking can drastically simplify building UIs. We’ve all used apps where the UI enters a weird unintended state after taking a path the developer didn’t expect. With React, bugs like this are much easier to track down. You don’t have to think as much about the user’s path through the system, instead focusing on making sure your view declarations can handle all possible shapes for your app’s state. This is a much easier problem to solve - and to test for. It is also more easily understood by the computer, so improvements to static analysis and type systems will only make these bugs easier to find.

React Native component definitions look and behave pretty much just like React for web components, but target native UI widgets instead of HTML. So instead of using a <div>, you would use a <View> (which on iOS gets rendered to a native UIView, and on Android, android.view). When your components’ data changes, React Native will calculate what in your view needs to be altered, and make the needed calls to whatever native UI widgets are displayed.

And it is fast! JavaScript isn’t as fast as native code can be, but for most tasks, JavaScript and React Native are more than capable of keeping your app running at 60 frames per second. Under the hood, your JavaScript code is run on its own thread, separate from the main UI thread. So even when your app is running complex logic, your UI can still be smoothly animating or scrolling at 60fps, so long as the UI isn’t blocked by the JS thread.

Many software frameworks promise that they will let you make a great app for Android and iOS, but the product frequently ends up somewhere in the middle without feeling truly native to either. By embracing the native platforms while still letting your app share the majority of its codebase between platforms, React Native enables developers to make awesome native apps their customers will love, without the increase in budget building two separate apps could entail.

Ease Of Learning

One of React’s greatest strengths is how readable it is, even to those unfamiliar with it. Many frameworks require that you learn a long list of concepts that are only useful within that framework, while ignoring language fundamentals. React does its absolute best to do the opposite. As an example, consider the difference between rendering a portion of a list of friends in React Native vs Ionic (AngularJS).

With Ionic, you use the ngRepeat directive. Let us say we have an array of friends, each of which contains the following fields: first_name, last_name and is_online. But we only want to show those friends that are currently online. Here is our controller:


function FriendCtrl($scope) {
    $scope.friends = [
        {
            first_name: 'John',
            last_name: 'Doe',
            is_online: true,
        },
        {
            first_name: 'Jane',
            last_name: 'Doe',
            is_online: true,
        },
        {
            first_name: 'Foo',
            last_name: 'Bar',
            is_online: false,
        }
    ];
}

And here is our view:


<div ng-controller="FriendCtrl">
    <ul>
        <li ng-repeat="friend in friends | filter:{is_online:true}">
            {{friend.last_name}}, {{friend.first_name}}
        </li>
    </ul>
</div>

If you aren’t familiar with Ionic/AngularJS, this code snippet raises some immediate questions. What is $scope? What is the syntax for filter? And how would I add additional behavior, like sorting the list of friends?

With React Native, you make use of your existing knowledge of language fundamentals, using the built-in filter and map functions.


const DemoComponent = React.createClass({
    render() {
        const friends = [
            {
                first_name: 'John',
                last_name: 'Doe',
                is_online: true,
            },
            {
                first_name: 'Jane',
                last_name: 'Doe',
                is_online: true,
            },
            {
                first_name: 'Foo',
                last_name: 'Bar',
                is_online: false,
            }
        ];

        return (
            <View>
                {friends
                    .filter(f => f.is_online)
                    .map(f => <View>{f.last_name}, {f.first_name}</View>)}
            </View>
        );
    }
});

While the React Native snippet still raises some questions (What does React.createClass do? What is render?), the fact that the bulk of the code here is just regular JavaScript means it will be more understandable and maintainable to newcomers.

As an experienced developer, using standard language features you already know will save you time, and make your code more understandable to other developers. But just as importantly, if you are less experienced with JavaScript, React serves as an excellent teaching tool. If you haven’t yet learned how to use map or filter, learning React will teach you those too. Learning ngRepeat only teaches you ngRepeat.

And that is before considering multiplatform mobile development. While there will be some pieces of platform-specific code in a React Native project that targets both iOS and Android, the majority will be shared and all of it will be understandable to a JavaScript developer.

Vibrant Ecosystem

Since the majority of your React Native code is just plain JavaScript, it reaps the benefits of all the advancements in the language and its ecosystem. Instead of waiting on your framework developers to implement all the array manipulation functions you want, why not just use lodash? For manipulating or displaying dates and times, just use Moment.js. And all those amazing new ES6 language features you’ve been waiting to try out? Not only is React a great fit, their use is encouraged!

Thanks to its declarative views, certain libraries are particularly suited for use with React Native. One I’d be remiss not to mention is redux. Described as a “predictable state container”, redux is an awesome library for manipulating your application’s state. Redux is highly testable, and encourages writing small functions that are explicit about what data they change. Once your state changes are written this way, your app can take advantage of powerful features, like global undo/redo and hot reloading.

Developer Experience

Happy developers are productive developers, and React Native has a great development environment. Instead of repeatedly waiting for your code to compile and your app to restart while making tiny edits, changes to a React Native codebase are made to your running app without the need to restart (see a demo of that here).

And if you’ve written any JavaScript before, you’re probably already familiar with the Chrome developer tools. When running React Native in development mode, you can attach to your desktop Chrome browser, so you’ll be right at home with its debugger and profiling tools. Attaching to Chrome works either in the simulator or connected to a physical device.

For creating your app’s layout, React Native uses flexbox. While every layout engine has its own learning curve, upsides and downsides, React Native’s support for flexbox means you can use the exact same layout code for Android, iOS and web, instead of learning three different engines.

And Beyond!

React Native apps consist entirely, or close to that, of JavaScript. If you let your mind wander, this opens up a world of opportunities.

Code Sharing

We’ve already discussed how React Native can share code between Android and iOS, but what about the web? Anything in a React project that doesn’t directly tie to a native platform is already sharable. Think about an app that can render on the server, in a web browser, or on Android or iOS - all driven by one shared codebase. While we aren’t quite there yet, the community is working on it. Keep an eye on the react-native-web project.

Live Updates

Anyone who has shipped an iOS app has experienced the frustration of waiting for App Store approval. With React Native, it is possible to do live updates to your app without going through the App Store - much like for a web app. Since the bulk of your app will be JavaScript, you can fetch updates on the fly over the network. There are already services to help with this like AppHub, or you could build it yourself. As long as your app is aware of what version it is running and knows how to check the server for a newer version, you can publish updates to your app whenever you like. Long app approval times aren’t a problem on Android, but you can still use live updates as a way of guaranteeing your customers have the latest and greatest version of your app installed.

Conclusion

Between the ease of development, quality of the apps built with it, and the richness of the platform and ecosystem, I’ve had a lot of fun learning and building with React Native. If you want to learn more, check out the links below!

Resources

Further Reading

Smashing Editorial (da, jb, ml, og, mrn)