Video

Want to see the full-length video right now for free?

Sign In with GitHub for Free Access

Notes

React Native

React Native is a project from Facebook that allows developers to use React to build native mobile applications. This presents an amazing opportunity as now we can use the same tools, workflows, and approach to build for both web and mobile, without sacrificing the native look and interactions users expect on mobile. Join thoughtbot iOS developer Giles Van Gruisen as he guides us into the world of React Native and explains why this is so exciting.

What Makes React Native Interesting

React at the Core

At the core, React Native is just React. There are many additional pieces that have been added to make React run on the native Android and iOS platforms, but at its core, this is still just React. The same component-based, declarative approach to building UIs that React popularized for the web is now available in the realm of mobile.

This is great for two reasons. One, React is a very interesting framework that brings a lot of great ideas forward, particularly the idea of designing dynamic web applications using a declarative, functional approach. Your UI is a function of the current state of the application data model, and that simplicity does wonders for helping us manage complexity and keep our applications as straightforward and maintainable as possible. Check out our Weekly Iteration episode on React for more detail on the core philosophy of React and why we like it.

Second, React Native makes it possible for developers who historically have stuck to the web to now build for mobile. React Native abstracts away most of the specifics of the mobile platforms and lets developers use the same approach they've used with React on the web, while still accessing and using platform specific UI elements and interactions as needed. The philosophy is summed up well in this quote from the React Native blog:

It's worth noting that we're not chasing "write once, run anywhere." Different platforms have different looks, feels, and capabilities, and as such, we should still be developing discrete apps for each platform, but the same set of engineers should be able to build applications for whatever platform they choose, without needing to learn a fundamentally different set of technologies for each. We call this approach "learn once, write anywhere."

React Native and Design

React Native also makes designing mobile applications much more straightforward and familiar, very similar to what it does for developing the applications. The combination of the HTML-like JSX syntax and the use of CSS-like styling (including support for flexbox layout!) makes designing React Native mobile applications a much more familiar and approachable task for designers with a web background.

This is very different from how design and layout work on the mobile platforms by default, and is a welcome change. Again, the power here comes from using the same techniques and thinking to build applications across both web and mobile.

Where Does React Native Fit?

While we're certainly excited about what React Native represents, its worth noting that it may not be an ideal choice in all situations. It's great for straightforward data-driven applications, but likely not an ideal choice when you need highly customized UI elements, interactions, animations, hardware-access, etc.

Much of the native platform is exposed via React Natives core components, but not everything. For example, with React Native you have access to vibration functionality on both platforms, but it is currently not possible to create a vibration pattern. That said, while you may hit some limitations like this, it is possible to build custom wrapper components to access more of the native platform functionality, so it is not an all-or-nothing proposition.

What Exactly is React Native?

React Native is a novel approach to building mobile applications using JavaScript and web technology. It's certainly not the first, with platforms like Phonegap and Cordova having paved the way. Those frameworks took a different approach in which they wrap a native frame around a webview, and then run a web (HTML, CSS, and JS) application in the webview. This is referred to as a "hybrid" application.

React Native instead runs your application code in a background thread, executing your JavaScript and then sending layout commands to a main thread, calling into native platform APIs to build and arrange truly native UIs. User interactions are communicated from this main thread to the background thread where any updates to the UI are computed (using Reacts wonderful declarative virtual DOM magic) and then updates are communicated back to the main thread.

A nice feature of this is that all interactions are automatically handled off the main thread, which means that the UI remains responsive, even while handling more complex computation.

What are The Main Benefits of React Native?

Single Paradigm and Code Reuse

As discussed above, one of the core benefits of React Native is that it opens up the world of mobile application development to developers and designers who historically had focused on the web. By bringing a common approach to both platforms, we now have a common way to build applications.

Another great benefit of React Native is code reuse across the various versions of an application. In a post discussing the process of building the Android version of their mobile ad manger (for which they had already built a React Native iOS version), Facebook shared that they were able to reuse ~85% of the code across the two platforms. That sounds like a nearly ideal ratio. Re-use the vast majority, but still allow for customizing that last ~15% to ensure solid integration and alignment with native platform interactions.

Build Cycle

Lastly, since React Native is using JavaScript to run the application, there is no longer a need to continually re-compile the application with each change. In fact, with each release React Native improves the development workflow with steps like removing the need to open Xcode, supporting live reloading, and the recent addition of support for hot reloading.

Demo Project

To dive in a bit deeper, we'll take a look at a very simple React Native app that displays three boxes, and allows the user to hide or show the boxes by pressing a button.

We can run the application with two commands:

# start the JS file watcher process to
# build and bundle the application code
$ react-native start

# start the iOS simulator to interact
# with out application
$ react-native run-ios

Example React Native Component

To start, we'll take a look at the main component of the application:

import React, {
  AppRegistry,
  Component,
  StyleSheet,
  Text,
  View,
  TouchableHighlight
} from 'react-native';

class WeeklyIterationDemo extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      boxesHidden: false,
    }
  }

  toggleBoxes() {
    console.log(this.state)
    this.setState({
      boxesHidden: !this.state.boxesHidden
    })
  }

  renderBoxes() {
    if (this.state.boxesHidden) {
      return (
        <View style={styles.boxesContainer}>
          <View styles={styles.box} />
          <View styles={styles.box} />
          <View styles={styles.box} />
        </View>
      )
    } else {
      return null;
    }
  }

  render() {
    var buttonText = this.state.boxesHidden ? "Show" : "Hide";

    return (
      <View style={styles.container}>
        <TouchableHighlight onPress{() => this.toggleBoxes()} style={styles.button}>
          <Text style={styles.buttonText}>{buttonText} boxes</Text>
        </TouchableHighlight>
        {this.renderBoxes()}
      </View>
    );
  }
}

To highlight a few of the interesting features at play in this example:

  1. import - import is a part of ES6 (check out our Weekly Iteration episode on ES6), but the nice thing is React Native handles all the compilation for you
  2. React - Again, worth noting that this is just React at the core. We toggle a property on our object and React handles updating the UI as needed. Nice and declarative.

Flexbox for Styling

React native includes support for flexbox style declarations, and will automatically convert those flexbox styles into the platform specific variant. Flexbox was a very welcome addition to the world of web design, making it drastically easier to build and style applications. The mobile world benefits perhaps even more so from the ability to use flexbox as the native platform layout and styling functionality is an often highlighted as being difficult to work with.

Check out our Weekly Iteration episode on Flexbox if you need a refresher.

Chrome DevTools Debugging

Another area where web developers will feel at home is that React Native allows us to use the Chrome Developer Tools for debugging. console.log and even debugger statements will just work, which makes building and debugging React Native applications very approachable for those new to the platform.

Hot Reloading

From its initial release, React Native has had a great story around rapid iteration and feedback cycles thanks to not needing to compile. It took things a step further with the addition of live reloading where the simulator would automatically reload the application when a file was updated. And now, with the addition of hot reloading, they've taken things to the next level.

With hot reloading, each time you save a component, the live code running in the simulator will update while maintaining the application state like the current view or the boxesHidden property in our demo. This may not read as that amazing, but in practice hot reloading can totally change the way in which we build applications, making tiny changes and immediately getting feedback.

Cross Platform Demo

Now we can dive a little deeper and take a look at an application the targets both Android and iOS from a single codebase.

Platform Agnostic Components

The majority of components available on React Native will abstract away the differences between the platforms. In this application, all but one of the components used will work on either platform without our code needing to handle the distinctions at all.

Looking at the code used, we can see that we're using the Navigator, ListView, Text, and View components, all without needing to worry about platform distinctions.

Platform Specific Component Implementations

The only component in our application that has platform specific implementations is our Button component. The nice thing is that React Native makes it very easy to opt into platform specific versions of components by simply naming the files with a platform specific file extension:

// button.ios.js file
import React, {
  TouchableHighlight
} from 'react-native'

export default class Button extends React.Component {
  render() {
    return <TouchableHighlight {...this.props} underlayColor={'#eee'} />
  }
}
import React, {
  TouchableNativeFeedback
} from 'react-native'

export default class Button extends React.Component {
  render() {
    return <TouchableNativeFeedback {...this.props} />
  }
}

Between the two, we can see that the only difference is in the touch specific implementation for Android vs iOS. With these two files defined, the code that uses this component can now be blissfully unaware of the platform distinctions, and simply import and use the component like any other.

import React, {
  StyleSheet,
  Text,
  View,
} from 'react-native'

import Button from './button'
import Quote from './quote'

export default class Row extends React.Component {
  // ... other functions omitted

  render() {
    return (
      <View>
        <Button onPress={this.navigateTo.bind(this)}>
          <View style={styles.rowContainer}>
            <Text style={styles.text} numberOfLines={1}>{this.truncatedQuote()}</Text>
          </View>
        </Button>
      </View>
    )
  }
}

The children are passed as a prop to our Button component, allowing us to define the platform specific implementation only where needed, and then use it via the abstracted component we've created. Nice!

React Native Everywhere?

While React starting as a project for building web applications, it very quickly was ported to a whole variety of platforms including canvas, server rendering, and even custom implementations like Netflix's Gibbon system which allows them to render React applications on a whole variety of embedded TV systems.

Not with React Native, we can target Android and iOS, but the momentum is only growing with Microsoft recently announcing React Native on the Universal Windows Platform. There is even a React Native for the Web project (which is not a joke, much as it sounds like one). This speaks to the power of the abstractions introduced by React, and the value of the "learn once, write anywhere" philosophy.

Where to Get Started

If you're interested in giving React Native a shot, the best place to start is the projects own Getting Started guide.