Lecture : 7 min. Auteur(s) : Tags :

While preparing our next React Native training, I learnt a lot on the library and discovered an amazing community with a lot of packages. I felt the need to share the treasures I found.

How to start your project

There are already many ways to start your project, the simplest and official way is with react-native-cli .

react-native init AwesomeProject will generate all the project files needed to start with iOS and Android platforms (ex: Xcode and Gradle configurations).

What if you need more ? Lucky you, I found three starter kits to bootstrap your project! Here are some explanations on each one, to help you choose the right one for your need. Be careful, they come with technical choices and some boilerplate code that you may not need.

Highly focused on testing and CI, this one comes with nice video tutorials to guide you through. The author explains his choices and help you understand the redux architecture. I find this a really good template to begin with.

Inspired from Snowflake with even more tools, like Auth0 integration, multi-environment configuration or Enzyme for testing. More advanced than Snowflake but also less accessible.

This one comes with generators that can help you iterate more quickly. Again, it is more complex than the others, with libs included (ie. react-native-maps) and another test mechanism built with AVA. I recommend this one for advanced users.

Architecture and navigation

All the previous starter kits are using Redux, this is a nice choice with React and it helps a lot managing the state of your application. The new NavigatorExperimental merged in React Native is already using reducers to handle the navigation state.

But this is not mandatory and you could just build your app without it, for example just using smart and dumb components, with the stateful Navigator component.

I think the main difficulty when implementing the navigation is the number of choices available. To help you with that, I’ll try to clarify each of the navigation options.

NavigatorIOS

The first option is a fully native one, only for iOS, sadly. It leverages the UIViewController to handle the navigation stack and the transition. This is the way to go if you are building only for iOS and you want to feel as close as possible to the system UI. Since the stack is handled natively, you could run into problems when trying to manage it on the JS side. It is also less customizable than the others.

Navigator

This navigation component is built only with JS and so is completely cross platform and customizable. Since all transitions are built in JS, opening a heavy page could lead to FPS drop and degrade the experience. The library proposes an InteractionManager to avoid doing work when transitioning with a method runAfterInteractions but keep in mind that this delays the render of your new scene. This component is also stateful, unlike the next one…

NavigationExperimental

As the name tells you, this one is experimental and varies across releases. Fortunately, @jlyman is keeping an updated repo after each release with the implementations.

NavigationExperimental relies on redux to handle the state and modify the navigation stack, this is the way to go if you want all your app to be managed by it. It needs more boilerplate code to start with but @jlyman and the official documentation will satisfy your copypasta addiction.

react-native-navigation

The last option is available as a module, and mentioned in the documentation page of NavigatorIOS. It provides a native navigation for both platforms and can be used with Redux! Since the navigation state is on the native side, the installation process involves editing the entry point and adding some boilerplate code in Objective-C and Java. The Android part is still a work in progress but I tried the examples and they all work really well. This is the way to go if you want to be as close as possible with the native UI and animation of the platforms.

Must have library

A lot of my research was into looking for the best components we could use to build our apps. Here is a tiny list of native and pure Javascript libraries for your development.

Javascript libraries

Since we are not in a browser context nor a nodejs context, library using window, document or node modules will not work. Here is a short list of the ones I find interesting:

MomentJS: fully featured date and time library

UnderscoreJS / lodash: toolkit to manipulate arrays, objects, strings…

ImmutableJS: immutable collections implementation

Redux thunk, redux saga: handling of asynchronous actions with Redux

React Native libraries

react-native-gifted-listview: list enhancement with pull to refresh and load more capability

react-native-gifted-form: many form widgets and customization

react-native-scrollable-tab-view: tabs navigation

redux devtools, reactotron: debug tools for Redux, time travel, logs and dispatching actions manually

react-native-drawer: drawer navigation built only with JS

react-native-elements: nice UI toolkit for faster development

Many many more… see js.coach

Test your app (or not)

Testing is at your discretion but the tooling is ready and waiting for you!

The official way seems to be Jest which provides mocks for React Native and a nice feature called Snapshot which allow developers to write fast tests to validate a component tree over time.

I saw other implementations using Enzyme and react-native-mock, closer to the ReactJS way. A good start is to look at the official implementation example by Airbnb.

import React, { View, Text, StyleSheet } from 'react-native'; import { shallow } from 'enzyme'; import MyComponent from '../src/MyComponent'; import { expect } from 'chai'; describe('<MyComponent />', () => { it('should render stuff', () => { const wrapper = shallow(<MyComponent />); expect(wrapper.length).to.equal(1); expect(wrapper.contains(<Text>I wonder if there will be any problems...</Text>)).to.equal(true); }); });

This covers up for unit testing in JS but you can also create functional tests, for this I tried Appium. This is an open source client-server software for manipulating simulator and device, the fun part is that the driver is implemented in many languages so you can write your tests also with JS and node. There is also a GUI to select manually the elements and generate boilerplate code.

Deployment

Assets

A tedious task when releasing an app is to create icons, images and splash screens for each device and platform. When using Titanium, we used Ticons which is a good cli library to integrate in your workflow and it also available as a website on http://ticons.fokkezb.nl/.

Ionic CLI has something similar that also supports PSD and AI files.

Both can be used with a React Native environment.

Building

The React Native documentation covers the basics for releasing your app. I suggest two services that will help you deliver faster.

CodePush is a SAAS service (by Microsoft) with a CLI and a native module to include in your app. It will allow to bypass the store release process for minor updates. It works by saving your JS code and assets on the server, your app check if updates are available and download it in background. The next app restart will have the updated version.

Another toolkit already used by many iOS and Android developers is Fastlane. This is an automation tool that will handle many repeated tasks like certification and profile generation or creating screenshots for each device size. It also lives versioned in a config file just next to your app, this is the ultimate time saving tool for mobile development.

Continuous integration

After setting up the tests in my app, I was looking for a CI supporting both iOS and Android. I looked at CircleCI which has a paid plan for OSX but instead I tried Bitrise which has also specific support for React Native and a free plan. After following the excellent tutorials from the Snowflake starter kit, I had a working build with jest tests, release bundle and release xcode build working! Below is the only file needed to make this work.

format_version: 1.1.0 default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git app: envs: - BITRISE_PROJECT_PATH: ios/example.xcodeproj opts: is_expand: false - BITRISE_SCHEME: example opts: is_expand: false trigger_map: - pattern: master is_pull_request_allowed: true workflow: primary workflows: primary: steps: - activate-ssh-key@3.1.1: title: Activate App SSH key inputs: - ssh_key_save_path: "$HOME/.ssh/steplib_ssh_step_id_rsa" - git-clone@3.3.3: inputs: - clone_depth: '1' - change-workdir@1.0.1: inputs: - path: example-react-native-app - is_create_path: 'false' - script@1.1.2: title: npm install inputs: - content: |- #!/bin/bash npm install - script@1.1.2: title: npm test inputs: - content: |- #!/bin/bash npm test - install-react-native@0.1.0: {} - react-native-bundle@0.2.0: inputs: - entry_file: "./index.ios.js" - out: ''

An amazing ecosystem

Building our training program was really awesome with all the amazing resources and people experimenting with the library. Developing a React Native app is not only writing JS code but also having the right toolkit to iterate quickly and have a first class app at the end.

If you want to know more and create an app from scratch during a three days session, head over to our React Native training.