a

Introduction to React Native

Traditionally, developing native iOS and Android applications has required the developer to use platform-specific programming languages and development environments. For iOS development, this means using Objective C or Swift and for Android development using JVM based languages such as Java, Scala or Kotlin. Releasing an application for both these platforms technically requires to develop two separate applications with different programming languages. This requires lots of development resources.

One of the popular approaches to unify the platform-specific development has been to utilize the browser as the rendering engine. Cordova is one of the most popular platforms for building cross-platform applications. It allows developing multi-platform applications using standard web technologies - HTML5, CSS3, and JavaScript. However, Cordova applications are running within a embedded browser window in the user's device. That is why these applications can not achieve the performance nor the look-and-feel of native applications that utilize actual native user interface components.

React Native is a framework for developing native Android and iOS applications using JavaScript and React. It provides a set of cross-platform components that behind the scenes utilize the platform's native components. Using React Native allows us to bring all the familiar features of React such as JSX, components, props, state, and hooks into native application development. On top of that we are able to utilize many familiar libraries in React ecosystem such as react-redux, react-apollo, react-router and many more.

The speed of development and gentle learning curve for developers familiar with React is one of the most important benefits of React Native. Here's a motivational quote from Coinbase's article Onboarding thousands of users with React Native on the benefits of React Native:

If we were to reduce the benefits of React Native to a single word, it would be “velocity”. On average, our team was able to onboard engineers in less time, share more code (which we expect will lead to future productivity boosts), and ultimately deliver features faster than if we had taken a purely native approach.

About this part

During this part, we will learn how to build an actual React Native application from bottom up. We will learn concepts such what are React Native's core components, how to create beautiful user interfaces, how to communicate with a server and how to test a React Native application.

We will be developing an application for rating GitHub repositories. Our application will have features such as, sorting and filtering reviewed repositories, registering a user, logging in and creating a review for a repository. The back end for the application will be provided for us so that we can solely focus on the React Native development. The final version of our application will look something like this:

fullstack content

All the exercises in this part have to be submitted into a single GitHub repository which will eventually contain the entire source code of your application. There will be model solutions available for each section of this part which you can use to fill in incomplete submissions. This part is structured based on the idea that you develop your application as you progress in the material. So do not wait until the exercises to start the development. Instead, develop your application in the same pace as the material progresses.

This part will heavily rely on concepts covered in the previous parts. Before starting this part you will need basic knowledge of JavaScript, React and GraphQL. Deep knowledge of server-side development is not required and all the server-side code is provided for you. However, we will be making network requests from your React Native applications, for example, using GraphQL queries. The recommended parts to complete before this part are part 1, part 2, part 5, part 7 and part 8.

Submitting exercises and earning credits

Exercises are submitted via the submissions system just like in the previous parts. Note that, exercises in this part are submitted to a different course instance than in parts 0-9. The parts 1-4 in the submission system refer to the sections a-d in this part. This means that you will be submitting exercises a single section at a time starting with this section, "Introduction to React Native", which is part 1 in the submission system.

During this part you will earn credits based on the number of exercises you complete. Completing at least 19 exercises in this part will earn you 1 credit. Completing at least 26 exercises in this part will earn you 2 credits.

Once you have completed the exercises and want to get the credits, let us know through the exercise submission system that you have completed the course:

fullstack content

Note that the "exam done in Moodle" note refers to the Full Stack Open course's exam, which has to be completed before you can earn credits from this part.

Initializing the application

To get started with our application we need to set up our development environment. We have learned from previous parts that there are useful tools for setting up React applications quickly such as Create React App. Luckily React Native has these kinds of tools as well.

For the development of our application, we will be using Expo. Expo is a platform that eases the setup, development, building, and deployment of React Native applications. Let's get started with Expo by installing the expo-cli command-line interface:

npm install --global expo-cli

Next, we can initialize our project in a rate-repository-app directory by running the following command:

expo init rate-repository-app

After running this command Expo will ask you to choose a template for the project. Within the Managed workflow section, choose the blank option (the one with the description "a minimal app as clean as an empty canvas").

Now that our application has been initialized, open the created rate-repository-app directory with an editor such as Visual Studio Code. The structure should be more or less the following:

fullstack content

We might spot some familiar files and directories such as package.json and node_modules. On top of those, the most relevant files are app.json file which contains Expo related configuration and App.js which is the root component of our application. Do not rename or move the App.js file because by default Expo imports it to register the root component.

Let's have look at scripts section of the package.json file which has the following scripts:

{
  // ...
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  // ...
}

Running the script npm start starts the Metro bundler which is a JavaScript bundler for React Native. It can be described as the Webpack of the React Native ecosystem. In addition to the Metro bundler, Expo development tools should be open in a browser window at http://localhost:19002. Expo development tools are a useful set of tools for viewing the application logs and starting the application in an emulator or in Expo's mobile application. We will get to emulators and Expo's mobile application soon, but first, let's start our application in a web browser by clicking the Run in web browser link:

fullstack content

After clicking the link we should soon see the text defined in the App.js file in a browser window. Open the App.js file with an editor and make a small change to the text in the Text component. After saving the file you should be able to see that the changes you have made into the code are visible in the browser window.

Setting up the development environment

We have had the first glance of our application using the Expo's browser view. Although the browser view is quite usable, it is still a quite poor simulation of the native environment. Let's have a look at the alternatives we have regarding the development environment.

Android and iOS devices such as tablets and phones can be emulated in computers using specific emulators. This is very useful for developing native applications. macOS users can use both Android and iOS emulators with their computers. Users of other operating systems such as Linux or Windows have to settle for Android emulators. Next, depending on your operating system follow one of these instructions on setting up an emulator:

After you have set up the emulator and it is running, start the Expo development tools as we did before, by running npm start. Depending on the emulator you are running either click the Run on Android device/emulator or Run on iOS simulator link. After clicking the link, Expo should connect to the emulator and you should eventually see the application in your emulator. Be patient, this might take a while.

In addition to emulators, there is one extremely useful way to develop React Native applications with Expo, the Expo mobile app. With Expo mobile app you can preview your application using your actual mobile device, which provides a bit more concrete development experience compared to emulators. To get started, install the Expo mobile app by following the instructions in the Expo's documentation. Note that the Expo mobile app can only open your application if your mobile device is connected to the same local network (e.g. connected to the same Wi-Fi network) as the computer you are using for development.

When the Expo mobile app is finished installing, open it up. Next, if the Expo development tools is not already running, start it by running npm start. In the bottom left corner of the development tools, you should be able to see a QR code. Within the Expo mobile app, press Scan QR Code and scan the QR code displayed in the development tools. The Expo mobile app should start building the JavaScript bundle and after it is finished you should be able to see your application. Now, every time you want to reopen your application in the Expo mobile app, you should be able to access the application without scanning the QR code by pressing it in the Recently opened list in the Projects view.

ESLint

Now that we are somewhat familiar with the development environment let's enhance our development experience even further by configuring a linter. We will be using ESLint which is already familiar to us from the previous parts. Let's get started by installing the dependencies:

npm install --save-dev eslint babel-eslint eslint-plugin-react

Next, let's add the ESLint configuration into a .eslintrc file into the rate-repository-app directory with the following content:

{
  "plugins": ["react"],
  "settings": {
    "react": {
      "version": "detect"
    }
  },
  "extends": ["eslint:recommended", "plugin:react/recommended"],
  "parser": "babel-eslint",
  "env": {
    "browser": true
  },
  "rules": {
    "react/prop-types": "off",
    "semi": "error"
  }
}

And finally, let's add a lint script to the package.json file to check the linting rules in specific files:

{
  // ...
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "lint": "eslint ./src/**/*.{js,jsx} App.js --no-error-on-unmatched-pattern"
  },
  // ...
}

In contrast to parts 1-8, we are using semicolons to terminate lines now, so we have added the rule semi to check that.

Now we can check that the linting rules are obeyed in JavaScript files in the src directory and in the App.js file by running npm run lint. We will be adding our future code to the src directory but because we haven't added any files there yet, we need the no-error-on-unmatched-pattern flag. Also if possible integrate ESLint with your editor. If you are using Visual Studio Code you can do that by, going to the extensions section and checking that the ESLint extension is installed and enabled:

fullstack content

The provided ESLint configuration contains only the basis for the configuration. Feel free to improve the configuration and add new plugins if you feel like it.

Viewing logs

Expo development tools can be used to display the log messages of the running application. Error and warning level messages are also visible in the emulator and the mobile app interface. Error messages will pop out as a red overlay whereas warning messages can be expanded by pressing the yellow alert dialog at the bottom of the screen. For debugging purposes, we can use the familiar console.log method to write debugging messages to the log.

Let's try this in practice. Start the Expo development tools by running npm start and open the application with either emulator or the mobile app. When the application is running you should be able to see your connected devices under the "Metro Bundler" in the top left corner of the developments tools:

fullstack content

Click on the device to open its logs. Next, open the App.js file and add a console.log message to the App component. After saving the file, you should be able to see your message in the logs.

Using the debugger

Inspecting messages logged from the code with the console.log method can be handy, but sometimes finding bugs or understanding how the application works require us to see the bigger picture. We might, for example, be interested in what is the state and the props of a certain component, or what is the response of a certain network request. In the previous parts, we have used the browser's developer tools for this kind of debugging. React Native Debugger is a tool that offers a similar set of debugging features for React Native applications.

Let's get started by installing React Native Debugger with the help of the installation instructions. Once the installation is complete, start the React Native Debugger, open a new debugger window (shortcuts: Command+T on macOS, Ctrl+T on Linux/Windows) and set the React Native packager port to 9001.

Next, we need to start our application and connect to the debugger. Start the application by running npm start. Once the application is running, open it with either an emulator or the Expo mobile app. Inside the emulator or the Expo mobile app, open the developer menu by following the instructions in the Expo's documentation. From the developer menu, select Debug remote JS to connect to the debugger. Now, you should be able to see the application's component tree in the debugger:

fullstack content

You can use the debugger to inspect the component's state and props as well as change them. Try finding the Text component rendered by the App component using the debugger. You can either use the search or go through the component tree. Once you have found the Text component in the tree, click it, and change the value of the children prop. The change should be automatically visible in the application's preview.

For more useful React Native application debugging tools, head out to the Expo's debugging documentation.