Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
React Native Blueprints
React Native Blueprints

React Native Blueprints: Create eight exciting native cross-platform mobile applications with JavaScript

eBook
€20.98 €29.99
Paperback
€36.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

React Native Blueprints

Shopping List

Most of the modern languages and frameworks used to present a to-do list as their sample app. It is a great way to understand the basics of a framework as user interaction, basic navigation, or how to structure code. We'll start in a more pragmatic way: building a shopping list app.

You will be able to develop this app in React Native code, build it for both iOS and Android, and finally install it on your phone. This way, you could not only show your friends what you built, but also understand missing features that you can build by yourself, thinking about user-interface improvements, and above all, motivating yourself to keep learning React Native as you feel its true potential. 

By the end of this chapter, you will have built a fully-functional shopping list that you can use on your phone and will have all the tools you need to create and maintain simple stateful apps.

Overview

One of the most powerful features of React Native is its cross-platform capabilities; we will build our shopping list app for both iOS and Android, reusing 99% of our code. Let's take a look at how the app will look on both platforms:

iOS:

After adding more products, this is how it will look:


Android:

After adding more products, this is how it will look:

The app will have a very similar user interface on both platforms, but we won't need to care much about the differences (for example, the back button on the Add a product screen), as they will be handled automatically by React Native.

It is important to understand that each platform has its own user interface patterns, and it's a good practice to follow them. For example, navigation is usually handled through tabs in iOS while Android prefers a drawer menu, so we should build both navigation patterns if we want happy users on both platforms. In any case, this is only a recommendation, and any user interface pattern could be built on every platform. In later chapters, we will see how to handle two different patterns in the most effective way within the same codebase.

The app comprises of two screens: your shopping list and a list of the products which could be added to your shopping list. The user can navigate from the Shopping List screen to the Add a product screen through the round blue button and back through the < Back button. We will also build a clear button in the shopping list screen (the round red button) and the ability to add and remove products on the Add a product screen.

We will be covering the following topics in this chapter:

  • Folder structure for a basic React Native project
  • React Native's basic CLI commands
  • Basic navigation
  • JS debugging
  • Live reloading
  • Styling with NativeBase
  • Lists
  • Basic state management
  • Handling events
  • AsyncStorage
  • Prompt popups
  • Distributing the app

Setting up our project

React Native has a very powerful CLI that we will need to install to get started with our project. To install, just run the following command in your command line (you might need to run this with sudo), if you don't have enough permissions:

npm install -g react-native-cli

Once the installation is finished, we can start using the React Native CLI by typing react-native. To start our project, we will run the following command:

react-native init --version="0.49.3" GroceriesList

This command will create a basic project named GroceriesList with all the dependencies and libraries you need to build the app on iOS and Android. Once the CLI has finished installing all the packages, you should have a folder structure similar to this:

The entry file for our project is index.js. If you want to see your initial app running on a simulator, you can use React Native's CLI again:

react-native run-ios

Or

react-native run-android

Provided you have XCode or Android Studio and Android Simulator installed, you should be able to see a sample screen on your simulator after compilation:

We have everything we need to set up to start implementing our app, but in order to easily debug and see our changes in the simulator, we need to enable two more features: remote JS debugging and live reloading.

For debugging, we will use React Native Debugger, a standalone app, based on the official debugger for React Native, which includes React Inspector and Redux DevTools. It can be downloaded following the instructions on its GitHub repository (https://github.com/jhen0409/react-native-debugger). For this debugger to work properly, we will need to enable Remote JS Debugging from within our app by opening a React Native development menu within the simulator by pressing command + ctrl + Z on iOS or command + M on Android.

If everything goes well, we should see the following menu appear:

   

Now, we will press two buttons: Debug Remote JS and Enable Live Reload. Once we are done with this, we have all our development environment up and ready to start writing React code.

Setting up the folder structure

Our app only comprises of two screens: Shopping List and Add Products. Since the state for such a simple app should be easy to manage, we won't add any library for state management (for example, Redux), as we will send the shared state through the navigation component. This should make our folder structure rather simple:

We have to create an src folder where we will store all our React code. The self-created file index.js will have the following code:

/*** index.js ***/

import { AppRegistry } from 'react-native';
import App from './src/main';
AppRegistry.registerComponent('GroceriesList', () => App);

In short, these files will import the common root code for our app, store it in a variable named App and later pass this variable to the AppRegistry through the registerComponent method. AppRegistry is the component to which we should register our root components. Once we do this, React Native will generate a JS bundle for our app and then run the app when it's ready by invoking AppRegistry.runApplication.

Most of the code we will be writing, will be placed inside the src folder. For this app, we will create our root component (main.js) in this folder, and a screens subfolder, in which we will store our two screens (ShoppingList and AddProduct).

Now let's install all the initial dependencies for our app before continue coding. In our project's root folder, we will need to run the following command:

npm install

Running that command will install all the basic dependencies for every React Native project. Let's now install the three packages we will be using for this specific app:

npm install native-base --save
npm install react-native-prompt-android --save
npm install react-navigation --save

Further ahead in this chapter, we will explain what each package will be used for.

Adding a Navigation component

Most mobile apps comprise of more than one screen, so we will need to be able to "travel" between those screens. In order to achieve this, we will need a Navigation component. React Native comes with a Navigator and a NavigatorIOS component out of the box, although the React maintainers recommend using an external navigation solution built by the community named react-navigation (https://github.com/react-community/react-navigation), which is very performant, well maintained, and rich in features, so we will use it for our app.

Because we already installed our module for navigation (react-navigation), we can set up and initialize our Navigation component inside our main.js file:

/*** src/main.js ***/

import React from 'react';
import { StackNavigator } from 'react-navigation';
import ShoppingList from './screens/ShoppingList.js';
import AddProduct from './screens/AddProduct.js';

const Navigator = StackNavigator({
ShoppingList: { screen: ShoppingList },
AddProduct: { screen: AddProduct }
});

export default class App extends React.Component {
constructor() {
super();
}

render() {
return <Navigator />;
}
}

Our root component imports both of the screens in our app (ShoppingList and AddProduct) and passes them to the StackNavigator function, which generates the Navigator component. Let's take a deeper look into how StackNavigator works.

StackNavigator provides a way for any app to transition between screens, where each new screen is placed on top of a stack. When we request the navigation to a new screen, StackNavigator will slide the new screen from the right and place a < Back button in the upper-right corner to go back to the previous screen in iOS or, will fade in from the bottom while a new screen is placing a <- arrow to go back in Android. With the same codebase, we will trigger familiar navigation patterns in iOS and Android. StackNavigator is also really simple to use, as we only need to pass the screens in our apps as a hash map, where the keys are the names we want for our screens and the values are the imported screens as React components. The result is a <Navigator/> component which we can render to initialize our app.

Styling our app with NativeBase

React Native includes a powerful way to style our components and screens using Flexbox and a CSS-like API but, for this app, we want to focus on the functionality aspect, so we will use a library including basic styled components as buttons, lists, icons, menus, forms, and many more. It can be seen as a Twitter Bootstrap for React Native.

There are several popular UI libraries, NativeBase and React Native elements being the two most popular and best supported. Out of these two, we will choose NativeBase, since it's documentation is slightly clearer for beginners.

You can find the detailed documentation on how NativeBase works on their website (https://docs.nativebase.io/), but we will go through the basics of installing and using some of their components in this chapter. We previously installed native-base as a dependency of our project through npm install but NativeBase includes some peer dependencies, which need to be linked and included in our iOS and Android native folders. Luckily, React Native already has a tool for finding out those dependencies and linking them; we just need to run:

react-native link

At this point, we have all the UI components from NativeBase fully available in our app. So, we can start building our first screen.

Building the ShoppingList screen

Our first screen will contain a list of the items we need to buy, so it will contain one list item per item we need to buy, including a button to mark that item as already bought. Moreover, we need a button to navigate to the AddProduct screen, which will allow us to add products to our list. Finally, we will add a button to clear the list of products, in case we want to start a new shopping list:

Let's start by creating ShoppingList.js inside the screens folder and importing all the UI components we will need from native-base and react-native (we will use an alert popup to warn the user before clearing all items). The main UI components we will be using are Fab (the blue and red round buttons), List, ListItem, CheckBox, Text, and Icon. To support our layout, we will be using Body, Container, Content, and Right, which are layout containers for the rest of our components.

Having all these components, we can create a simple version of our ShoppingList component:

/*** ShoppingList.js ***/

import React from 'react';
import { Alert } from 'react-native';
import {
Body,
Container,
Content,
Right,
Text,
CheckBox,
List,
ListItem,
Fab,
Icon
} from 'native-base';

export default class ShoppingList extends React.Component {
static navigationOptions = {
title: 'My Groceries List'
};
/*** Render ***/
render() {
return (
<Container>
<Content>
<List>
<ListItem>
<Body>
<Text>'Name of the product'</Text>
</Body>
<Right>
<CheckBox
checked={false}
/>
</Right>
</ListItem>
</List>
</Content>
<Fab
style={{ backgroundColor: '#5067FF' }}
position="bottomRight"
>
<Icon name="add" />
</Fab>
<Fab
style={{ backgroundColor: 'red' }}
position="bottomLeft"
>
<Icon ios="ios-remove" android="md-remove" />
</Fab>
</Container>
);
}
}

This is just a dumb component statically displaying the components we will be using on this screen. Some things to note:

  • navigationOptions is a static attribute which will be used by <Navigator> to configure how the navigation would behave. In our case, we want to display My Groceries List as the title for this screen.
  • For native-base to do its magic, we need to use <Container> and <Content> to properly form the layout.
  • Fab buttons are placed outside <Content>, so they can float over the left and right-bottom corners.
  • Each ListItem contains a <Body> (main text) and a <Right> (icons aligned to the right).

Since we enabled Live Reload in our first steps, we should see the app reloading after saving our newly created file. All the UI elements are now in place, but they are not functional since we didn't add any state. This should be our next step.

Adding state to our screen

Let's add some initial state to our ShoppingList screen to populate the list with actual dynamic data. We will start by creating a constructor and setting the initial state there:

/*** ShoppingList.js ***/

...
constructor(props) {
super(props);
this.state = {
products: [{ id: 1, name: 'bread' }, { id: 2, name: 'eggs' }]
};
}
...

Now, we can render that state inside of <List> (inside the render method):

/*** ShoppingList.js ***/

...
<List>
{
this.state.products.map(p => {
return (
<ListItem
key={p.id}
>
<Body>
<Text style={{ color: p.gotten ? '#bbb' : '#000' }}>
{p.name}
</Text>
</Body>
<Right>
<CheckBox
checked={p.gotten}
/>
</Right>
</ListItem>
);
}
)}
</List>
...

We now rely on a list of products inside our component's state, each product storing an id, a name, and gotten properties. When modifying this state, we will automatically be re-rendering the list.

Now, it's time to add some event handlers, so we can modify the state at the users' command or navigate to the AddProduct screen.

Adding event handlers 

All the interaction with the user will happen through event handlers in React Native. Depending on the controller, we will have different events which can be triggered. The most common event is onPress, as it will be triggered every time we push a button, a checkbox, or a view in general. Let's add some onPress handlers for all the components which can be pushed in our screen:

/*** ShoppingList.js ***/

...
render() {
return (
<Container>
<Content>
<List>
{this.state.products.map(p => {
return (
<ListItem
key={p.id}
onPress={this._handleProductPress.bind(this, p)}
>
<Body>
<Text style={{ color: p.gotten ? '#bbb' : '#000' }}>
{p.name}
</Text>
</Body>
<Right>
<CheckBox
checked={p.gotten}
onPress={this._handleProductPress.bind(this, p)}
/>
</Right>
</ListItem>
);
})}
</List>
</Content>
<Fab
style={{ backgroundColor: '#5067FF' }}
position="bottomRight"
onPress={this._handleAddProductPress.bind(this)}
>
<Icon name="add" />
</Fab>
<Fab
style={{ backgroundColor: 'red' }}
position="bottomLeft"
onPress={this._handleClearPress.bind(this)}
>
<Icon ios="ios-remove" android="md-remove" />
</Fab>
</Container>
);
}
...

Notice we added three onPress event handlers:

  • On <ListItem>, to react when the user taps on one product in the list
  • On <CheckBox>, to react when the user taps on the checkbox icon next to every product in the list
  • On both the <Fab> buttons

If you know React, you probably understand why we use .bind in all our handler functions, but, in case you have doubts, .bind will make sure we can use this inside the definition of our handlers as a reference to the component itself instead of the global scope. This will allow us to call methods inside our components as this.setState or read our component's attributes, such as this.props and this.state.

For the cases when the user taps on a specific product, we also bind the product itself, so we can use them inside our event handlers.

Now, let's define the functions which will serve as event handlers:

/*** ShoppingList.js ***/

...
_handleProductPress(product) {
this.state.products.forEach(p => {
if (product.id === p.id) {
p.gotten = !p.gotten;
}
return p;
});

this.setState({ products: this.state.products });
}
...

First, let's create a handler for when the user taps on a product from our shopping list or in its checkbox. We want to mark the product as gotten (or unmark it if it was already gotten), so we will update the state with the product marked properly.

Next, we will add a handler for the blue <Fab> button to navigate to the AddProduct screen:

/*** ShoppingList.js ***/

...
_handleAddProductPress() {
this.props.navigation.navigate('AddProduct', {
addProduct: product => {
this.setState({
products: this.state.products.concat(product)
});
},
deleteProduct: product => {
this.setState({
products: this.state.products.filter(p => p.id !== product.id)
});
},
productsInList: this.state.products
});
}
...

This handler uses this.props.navigation, which is a property automatically passed by the Navigator component from react-navigation. This property contains a method named navigate, receiving the name of the screen to which the app should navigate plus an object which can be used as a global state. In the case of this app, we will store three keys:

  • addProduct: One function to allow the AddProduct screen to modify the ShoppingList component's state to reflect the action of adding a new product to the shopping list.
  • deleteProduct: One function to allow the AddProduct screen to modify the ShoppingList component's state to reflect the action of removing a product from the shopping list.
  • productsInList: A variable holding the list of products is already on the shopping list, so the AddProducts screen can know which products were already added to the shopping list and display those as "already added", preventing the addition of duplicate items.

Handling state within the navigation should be seen as a workaround for simple apps containing a limited number of screens. In larger apps (as we will see in later chapters), a state management library, such as Redux or MobX, should be used to keep the separation between pure data and user interface handling.

We will add the last handler for the blue <Fab> button, which enables the user to clear all the items in the shopping list in case you want to start a new list:

/*** ShoppingList.js ***/

...
_handleClearPress() {
Alert.alert('Clear all items?', null, [
{ text: 'Cancel' },
{ text: 'Ok', onPress: () => this.setState({ products: [] }) }
]);
}
...

We are using Alert to prompt the user for confirmation before clearing all the elements in our shopping list. Once the user confirms this action, we will empty the products attribute in our component's state.

Putting it all together

Let's see how the whole component's structure would look like when putting all the methods together:

/*** ShoppingList.js ***/

import React from 'react';
import { Alert } from 'react-native';
import { ... } from 'native-base';

export default class ShoppingList extends React.Component {
static navigationOptions = {
title: 'My Groceries List'
};

constructor(props) {
...
}

/*** User Actions Handlers ***/
_handleProductPress(product) {
...
}

_handleAddProductPress() {
...
}

_handleClearPress() {
...
}

/*** Render ***/
render() {
...
}
}

The structure of a React Native component is very similar to a normal React component. We need to import React itself and then some components to build up our screen. We also have several event handlers (which we have prefixed with an underscore as a mere convention) and finally a render method to display our components using standard JSX.

The only difference with a React web app is the fact that we are using React Native UI components instead of DOM components. 

Building the AddProduct screen

As the user will have the need of adding new products to the shopping list, we need to build a screen in which we can prompt the user for the name of the product to be added and save it in the phone's storage for later use.

Using AsyncStorage

When building a React Native app, it's important to understand how mobile devices handle the memory used by each app. Our app will be sharing the memory with the rest of the apps in the device so, eventually, the memory which is using our app will be claimed by a different app. Therefore, we cannot rely on putting data in memory for later use. In case we want to make sure the data is available across users of our app, we need to store that data in the device's persistent storage.

React Native offers an API to handle the communication with the persistent storage in our mobile devices and this API is the same on iOS and Android, so we can write cross-platform code comfortably.

The API is named AsyncStorage, and we can use it after importing from React Native:

import { AsyncStorage } from 'react-native';

We will only use two methods from AsyncStorage: getItem and setItem. For example, we will create within our screen a local function to handle the addition of a product to the full list of products:

/*** AddProduct ***/

...
async addNewProduct(name) {
const newProductsList = this.state.allProducts.concat({
name: name,
id: Math.floor(Math.random() * 100000)
});

await AsyncStorage.setItem(
'@allProducts',
JSON.stringify(newProductsList)
);

this.setState({
allProducts: newProductsList
});
}
...

There are some interesting things to note here:

  • We are using ES7 features such as async and await to handle asynchronous calls instead of promises or callbacks. Understanding ES7 is outside the scope of this book, but it is recommended to learn and understand about the use of async and await, as it's a very powerful feature we will be using extensively throughout this book.
  • Every time we add a product to allProducts, we also call AsyncStorage.setItem to permanently store the product in our device's storage. This action ensures that the products added by the user will be available even when the operating system clears the memory used by our app.
  • We need to pass two parameters to setItem (and also to getItem): a key and a value. Both of them must be strings, so we would need to use JSON.stringify, if we want to store the JSON-formatted data.

Adding state to our screen

As we have just seen, we will be using an attribute in our component's state named allProducts, which will contain the full list of products the user can add to the shopping list. 

We can initialize this state inside the component's constructor to give the user a gist of what he/she will be seeing on this screen even during the first run of the app (this is a trick used by many modern apps to onboard users by faking a used state):

/*** AddProduct.js ***/

...
constructor(props) {
super(props);
this.state = {
allProducts: [
{ id: 1, name: 'bread' },
{ id: 2, name: 'eggs' },
{ id: 3, name: 'paper towels' },
{ id: 4, name: 'milk' }
],
productsInList: []
};
}
...

Besides allProducts, we will also have a productsInList array, holding all the products which are already added to the current shopping list. This will allow us to mark the product as Already in shopping list, preventing the user from trying to add the same product twice in the list.

This constructor will be very useful for our app's first run but once the user has added products (and therefore saved them in persistent storage), we want those products to display instead of this test data. In order to achieve this functionality, we should read the saved products from AsyncStorage and set it as the initial allProducts value in our state. We will do this on componentWillMount:

/*** AddProduct.js ***/

...
async componentWillMount() {
const savedProducts = await AsyncStorage.getItem('@allProducts');
if(savedProducts) {
this.setState({
allProducts: JSON.parse(savedProducts)
});
}

this.setState({
productsInList: this.props.navigation.state.params.productsInList
});
}
...

We are updating the state once the screen is ready to be mounted. First, we will update the allProducts value by reading it from the persistent storage. Then, we will update the list productsInList based on what the ShoppingList screen has set as the state in the navigation property.

With this state, we can build our list of products, which can be added to the shopping list:

/*** AddProduct ***/

...
render(){
<List>
{this.state.allProducts.map(product => {
const productIsInList = this.state.productsInList.find(
p => p.id === product.id
);
return (
<ListItem key={product.id}>
<Body>
<Text
style={{
color: productIsInList ? '#bbb' : '#000'
}}
>
{product.name}
</Text>
{
productIsInList &&
<Text note>
{'Already in shopping list'}
</Text>
}
</Body>
</ListItem>
);
}
)}
</List>
}
...

Inside our render method, we will use an Array.map function to iterate and print each possible product, checking if the product is already added to the current shopping list to display a note, warning the user: Already in shopping list

Of course, we still need to add a better layout, buttons, and event handlers for all the possible user actions. Let's start improving our render method to put all the functionality in place. 

Adding event listeners

As it happened with the ShoppingList screen, we want the user to be able to interact with our AddProduct component, so we will add some event handlers to respond to some user actions.

Our render method should then look something like this:

/*** AddProduct.js ***/

...
render() {
return (
<Container>
<Content>
<List>
{this.state.allProducts.map(product => {
const productIsInList = this.state.productsInList.
find(p => p.id === product.id);
return (
<ListItem
key={product.id}
onPress={this._handleProductPress.bind
(this, product)}
>
<Body>
<Text
style={{ color: productIsInList? '#bbb' : '#000' }}
>
{product.name}
</Text>
{
productIsInList &&
<Text note>
{'Already in shopping list'}
</Text>
}
</Body>
<Right>
<Icon
ios="ios-remove-circle"
android="md-remove-circle"
style={{ color: 'red' }}
onPress={this._handleRemovePress.bind(this,
product )}
/>
</Right>
</ListItem>
);
})}
</List>
</Content>
<Fab
style={{ backgroundColor: '#5067FF' }}
position="bottomRight"
onPress={this._handleAddProductPress.bind(this)}
>
<Icon name="add" />
</Fab>
</Container>
);
}
...

There are three event handlers responding to the three press events in this component:

  • On the blue <Fab> button, which is in charge of adding new products to the products list
  • On each <ListItem>, which will add the product to the shopping list
  • On the delete icons inside each <ListItem> to remove this product from the list of the products, which can be added to the shopping list

Let's start adding new products to the available products list once the user presses the <Fab> button:

/*** AddProduct.js ***/

...
_handleAddProductPress() {
prompt(
'Enter product name',
'',
[
{ text: 'Cancel', style: 'cancel' },
{ text: 'OK', onPress: this.addNewProduct.bind(this) }
],
{
type: 'plain-text'
}
);
}
...

We are using here the prompt function from the react-native-prompt-android module. Despite its name, it's a cross-platform prompt-on-a-pop-up library, which we will use to add products through the addNewProduct function we created before. We need to import the prompt function before we use it, as follows:

import prompt from 'react-native-prompt-android';

And here is the output:

Once the user enters the name of the product and presses OK, the product will be added to the list so that we can move to the next event handler, adding products to the shopping list when the user taps on the product name:

/*** AddProduct.js ***/

...
_handleProductPress(product) {
const productIndex = this.state.productsInList.findIndex(
p => p.id === product.id
);
if (productIndex > -1) {
this.setState({
productsInList: this.state.productsInList.filter(
p => p.id !== product.id
)
});
this.props.navigation.state.params.deleteProduct(product);
} else {
this.setState({
productsInList: this.state.productsInList.concat(product)
});
this.props.navigation.state.params.addProduct(product);
}
}
...

This handler checks if the selected product is on the shopping list already. If it is, it will remove it by calling deleteProduct from the navigation state and also from the component's state by calling setState . Otherwise, it will add the product to the shopping list by calling addProduct in the navigation state and refresh the local state by calling setState.

Finally, we will add an event handler for the delete icon on each of the <ListItems>, so the user can remove products from the list of available products:

/*** AddProduct.js ***/

...
async _handleRemovePress(product) {
this.setState({
allProducts: this.state.allProducts.filter(p => p.id !== product.id)
});
await AsyncStorage.setItem(
'@allProducts',
JSON.stringify(
this.state.allProducts.filter(p => p.id !== product.id)
)
);
}
...

We need to remove the product from the component's local state, but also from the AsyncStorage so it doesn't show during later runs of our app.

Putting it all together

We have all the pieces to build our AddProduct screen, so let's take a look at the general structure of this component:

import React from 'react';
import prompt from 'react-native-prompt-android';
import { AsyncStorage } from 'react-native';
import {
...
} from 'native-base';

export default class AddProduct extends React.Component {
static navigationOptions = {
title: 'Add a product'
};

constructor(props) {
...
}

async componentWillMount() {
...
}

async addNewProduct(name) {
...
}

/*** User Actions Handlers ***/
_handleProductPress(product) {
...
}

_handleAddProductPress() {
...
}

async _handleRemovePress(product) {
...
}

/*** Render ***/
render() {
....
}
}

We have a very similar structure to the one we built for ShoppingList : the navigatorOptions constructor building the initial state, user action handlers, and a render method. In this case, we added a couple of async methods as a convenient way to deal with AsyncStorage.

Installing and distributing the app

Running our app on a simulator/emulator is a very reliable way to feel how our app will behave in a mobile device. We can simulate touch gestures, poor network connectivity environments, or even memory problems, when working in simulators/emulators. But eventually, we would like to deploy the app to a physical device, so we could perform a more in-depth testing.

There are several options to install or distribute an app built in React Native, the direct cable connection being the easiest one. Facebook keeps an updated guide on how to achieve direct installation on React Native's site (https://facebook.github.io/react-native/docs/running-on-device.html), but there are other alternatives when the time comes to distribute the app to other developers, testers, or designated users.

Testflight

Testflight (https://developer.apple.com/testflight/) is an awesome tool for distributing the app to beta testers and developers, but it comes with a big drawback--it only works for iOS. It's really simple to set up and use as it is integrated into iTunes Connect, and Apple considers it the official tool for distributing apps within the development team. On top of that, it's absolutely free, and it's usage limits are quite large:

  • Up to 25 testers in your team
  • Up to 30 devices per tester in your team
  • Up to 2,000 external testers outside your team (with grouping capabilities)

In short, Testflight is the platform to choose when you target your apps only to iOS devices.

Since, in this book, we want to focus on cross-platform development, we will introduce other alternatives to distribute our apps to iOS and Android devices from the same platform.

Diawi

Diawi (http://diawi.com) is a website where developers can upload their .ipa and .apk files (the compiled app) and share the links with anybody, so the app can be downloaded and installed on any iOS or Android device connected to the internet. The process is simple: 

  1. Build the .ipa (iOS) / .apk (Android) in XCode/Android studio.
  2. Drag and drop the generated .ipa/.apk file into Diawi's site.
  3. Share the link created by Diawi with the list of testers by email or any other method.

Links are private and can be password protected for those apps with the higher need of security. The main downside is the management of the testing devices, as once the links are distributed, Diawi loses control over them, so the developer cannot know which versions were downloaded and tested. If managing the list of testers manually is an option, Diawi is a good alternative to Testflight.

Installr

If we are in need of managing what versions were distributed to which testers and whether they have already started testing the app or not, we should give Installr (https://www.installrapp.com) a try, since functionality-wise it is quite similar to Diawi, but it also includes a dashboard to control who are the users, which apps were sent to them individually, and the status of the app in the testing device (not installed, installed, or opened). This dashboard is quite powerful and definitely a big plus when one of our requirements is to have good visibility over our testers, devices, and builds.

The downside of Installr is its free plan only covers three testing devices per build, although they offer a cheap one-time pay scheme in case we really want to have that number increased. It's a very reasonable option when we are in need of visibility and cross-platform distribution.

Summary

During the course of this chapter, we learned how to start up a React Native project, building an app which includes basic navigation and handling several user interactions. We saw how to handle persistent data and basic states using the navigation module, so we could transition through the screens in our project.

All these patterns can be used to build lots of simple apps, but in the next chapter, we will dive deeper into more complex navigation patterns and how to communicate and process external data fetched from the internet, which will enable us to structure and prepare our app for growing. On top of that, we will use MobX, a JavaScript library, for state management, which will make our domain data available to all the screens inside our app in a very simple and effective way.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • ? Build quirky and fun projects from scratch and become efficient with React Native
  • ? Learn to build professional Android and iOS applications with your JavaScript skills
  • ? Use Isomorphic principles to build mobile apps that offer a native user experience

Description

Considering the success of the React framework, Facebook recently introduced a new mobile development framework called React Native. With React Native's game-changing approach to hybrid mobile development, you can build native mobile applications that are much more powerful, interactive, and faster by using JavaScript This project-based guide takes you through eight projects to help you gain a sound understanding of the framework and helps you build mobile apps with native user experience. Starting with a simple standalone groceries list app, you will progressively move on to building advanced apps by adding connectivity with external APIs, using native features, such as the camera or microphone, in the mobile device, integrating with state management libraries such as Redux or MobX, or leveraging React Native’s performance by building a full-featured game. This book covers the entire feature set of React Native, starting from the simplest (layout or navigation libraries) to the most advanced (integration with native code) features. By the end of this book, you’ll be able to build professional Android and iOS applications using React Native.

Who is this book for?

This book is for developers who want to use their JavaScript knowledge for mobile development. Prior knowledge of React will be beneficial.

What you will learn

  • ? Structure React Native projects to ease maintenance and extensibility
  • ? Optimize a project to speed up development
  • ? Make a React Native project production-ready
  • ? Use external modules to speed up the development and maintenance of your projects
  • ? Explore the different UI and code patterns to be used for iOS and Android
  • ? Get to know the best practices when building apps in React Native
Estimated delivery fee Deliver to Slovakia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Nov 08, 2017
Length: 346 pages
Edition : 1st
Language : English
ISBN-13 : 9781787288096
Vendor :
Facebook
Category :
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Slovakia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Publication date : Nov 08, 2017
Length: 346 pages
Edition : 1st
Language : English
ISBN-13 : 9781787288096
Vendor :
Facebook
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 115.97
React Native Blueprints
€36.99
Progressive Web Apps with React
€36.99
React and React Native
€41.99
Total 115.97 Stars icon

Table of Contents

8 Chapters
Shopping List Chevron down icon Chevron up icon
RSS Reader Chevron down icon Chevron up icon
Car Booking App Chevron down icon Chevron up icon
Image Sharing App Chevron down icon Chevron up icon
Guitar Tuner Chevron down icon Chevron up icon
Messaging App Chevron down icon Chevron up icon
Game Chevron down icon Chevron up icon
E-Commerce App Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.8
(4 Ratings)
5 star 25%
4 star 50%
3 star 0%
2 star 25%
1 star 0%
Rhys Oct 19, 2019
Full star icon Full star icon Empty star icon Empty star icon Empty star icon 2
This appears to have been a good book on react native for the beginner.However it is now two years since publication and things have moved on.Many of the functions used in the code examples of book have been deprecated in the latest versions and will no longer work. Trying to get the older version of the framework may require some additional messing about with simulators.If you are a total beginner try to find something more up to date to avoid additional stress.
Amazon Verified review Amazon
JH Apr 09, 2018
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
This book seems well organized and good intentioned but it is not very clear how to get the demo apps to run, partially that one of the side-effects of React Native as a world that evolves quickly. Wish some more care was given to the nuances of a Firebase installation and so on but since that technology also changes so fast, maybe this is asking for the impossible.
Amazon Verified review Amazon
Vincent A. Jan 13, 2018
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
Good book! A couple of things could have been done better. The chapters don't match the samples gotten from the web.. But a good book overall.
Amazon Verified review Amazon
Sebastian Galiano Dec 16, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Probably one of the best books in the market to learn how to build mobile applications using React Native. It gave me the insights and examples needed to start developing react native apps.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela