From React to React Native in 30 Minutes

September 2nd, 2015 | By José Magalhães | 5 min read

All you need is React and JavaScript to create compelling native mobile apps that work on iOS.

For those who have never heard of React Native, it is a new library that allows you to use React on different platforms, including mobile devices. The difference with React is that instead of HTML components, you use the native components of the gadget where your application will run.

Today, we explain how to create a simple iOS application in 30 minutes, going from React to React Native. In this example, we are building an application for iOS. You can find the source code in this GitHub repository.

Benefits from our tutorial:

  • Learn all about the theory behind React Native

  • Explore its core concepts

  • Understand how to build an iOS app quickly.


We’ve started getting familiar with it by setting up a new project by following the instructions found in the documents:

npm install - g react - native - cli
react - native init todo

The first command installs react-native-cli globally, giving us the react-native “binary” tool, while the second creates a project ready to work with Xcode (Mac OS X required) and another editor of choice.

The above commands will create the following directory structure:

iOS /
    node_modules /

Besides all the iOS files and assets, we can find an index.ios.js file inside the project, which represents the entry point of our UI application. There’s a typical React class.

Below is the content of index.ios.js:

 * Sample React Native App
'use strict';

var React = require('react-native');
var {
} = React;

var todo = React.createClass({
    render: function() {
        return ( < View style = {
            } >
            < Text style = {
            } >
            Welcome to React Native!
            < /Text> < Text style = {
            } >
            To get started, edit index.ios.js < /Text> < Text style = {
            } >
            Press Cmd + R to reload, {
            Cmd + D or shake
            for dev menu < /Text> < /View>

var styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,

AppRegistry.registerComponent('todo', () => todo);

At this point, we can already see some differences: no HTML components, only components from the iOS SDK, and a StyleSheet factory with style properties that resemble CSS but are limited to what iOS offers.


Our goal is now to create a small interface with a list that allows us to add entries to it and persist them on the device so that it loads whenever we reopen the application.

Component State

In the component’s state, we’ll be storing the list of items on the to-do list, that same list in the form of a native DataSource, and the text field value of the input that allows creating new entries.

Keep in mind that this is only an example. Ideally, you would have different components to handle the list and the creation of a new entry.

getInitialState() {
    var itemsDS = new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2
    var items = [];
    this.getStorage().then((items) => this.setItems(items));
    return {
        itemsDS: itemsDS.cloneWithRows(items),
            text: ''


First, we’ve implemented our render method, a simple ScrollView composed of a ListView, a TextInput, and a TouchableWithoutFeedback button:

render() {
        return ( < ScrollView >
            < ListView style = {
            dataSource = {
            renderRow = {
                (rowData) => 
                   <Text>{rowData} </Text>
             <TextInput style = {styles.input}
                onChange = {this.onChange}
                value = {this.state.text }/> 
             <TouchableWithoutFeedback onPress = {this.onPress} >
               <Text style = {styles.submit}> 
                  Add entry </Text> 
             < /TouchableWithoutFeedback> < /ScrollView>


There are two main events in the UI: when we change the TextInput, we must update the component state, and when we press the TouchableWithoutFeedback component, we must add an entry to our ListView data source.

onChange(event) {
        text: event.nativeEvent.text

onPress() {
    if (this.state.text) {
            text: ''

setItems(items) {
    var itemsDS = this.state.itemsDS.cloneWithRows(items);
        items, itemsDS

Data Persistence

In order to persist the data of our application, we’re using a native API called AsyncStorage, which is pretty similar to localStorage.

The difference is that it’s async and it returns promises (yes!). We’ve created two methods to handle reading and writing to the storage:

getStorage() {
    return AsyncStorage
        .then((items) => JSON.parse(items));

updateStorage() {
    return AsyncStorage.setItem('items', JSON.stringify(this.state.items));


Styling is not the focus of our experience. However, you can easily tweak the look and feel of your application by using the StyleSheet API provided by React Native.

In our example, we’ve painted Picasso in the following styles:

var styles = StyleSheet.create({
    list: {
        flex: 1,
        paddingBottom: 25,
        paddingRight: 25,
        paddingLeft: 25,
        marginBottom: 10,
        backgroundColor: '#F5FCFF'
    input: {
        flex: 1,
        height: 25,
        marginRight: 20,
        marginLeft: 20,
        padding: 5,
        borderWidth: 1,
        borderColor: '#333',
        fontSize: 20
    submit: {
        flex: 1,
        alignSelf: 'center',
        margin: 20,
        padding: 5,
        backgroundColor: '#333333',
        borderWidth: 1,
        borderColor: '#333',
        borderRadius: 20

Objective-C Modules

In case you’re wondering how does React Native play with other Objective-C modules, it’s easy to export a module so that you can use it on your JavaScript code:

import "RCTBridgeModule.h"

interface MyModule: NSObject < RCTBridgeModule > @end

Then, inside your JavaScript code:

var MyModule = require('NativeModules').MyModule;

Registering the component

Finally, we must register our main component (ToDo) with the AppRegistry:

AppRegistry.registerComponent('todo', () => ToDo);

iOS development in 30 minutes with React Native

I’ve had next to zero experience with iOS development so I must say that it was nice to have a small application up and running in less than 30 minutes, though part of the documentation is incomplete (where’s the ListView.DataSource API described?) and React errors aren’t always helpful in finding the root cause.

Besides that, all the principles behind React still apply, so if you’re already experienced with it, you’ll find yourself coding reusable components in no time.

Overall, this looks like a very good alternative to other solutions such as Appcelerator and PhoneGap, which unfortunately cut you off from direct access to the native APIs. In this case, you’re working natively with a little JavaScript sugar on top of it.

Lastly, if you're building React applications with sensitive logic, be sure to protect them against code theft and reverse engineering.

Start your free trial with Jscrambler to protect your application's source code.


The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.

View All Articles

Must read next

Web Development

Changing App Themes Using React Native, Styled Components and Redux

In this tutorial, we explore how to add a dark mode to a simple React Native app using styled components for styling and Redux for state management.

October 2, 2019 | By Aman Mittal | 9 min read

Web Development

How To Use React Native AsyncStorage

Persisting data in mobile apps can be valuable to increase the user experience. In this post, we show how to implement and use this asynchronously in React Native.

April 29, 2022 | By Aman Mittal | 6 min read

Section Divider

Subscribe to Our Newsletter