Skip to content

The React Native Guide I Wish I Had! - Part 1: Environment and Stateless Components

March 22, 2021Benjamin Gowers11 min read

During my first week at Theodo, I had a lot to learn about the main technologies used within the company. I focused my attention on learning to build a simple React Native application using Typescript and Redux.


Quick Links

→ Part 1 - focuses on setting up your environment for react native, typescript and redux, as well as creating stateless components for a Todos app. (you are here!)

Part 2 - focuses on integrating redux and adding stateful components to your Todos app.


Table of Contents

Project Source
Introduction
Environment Setup
   Technologies
       Homebrew
       Node Version Manager
       Node & NPM
       React Native CLI
   Text Editor
The Todos App
   Creating The App
       Installing Icons
   Folder Structure
   Designing Components
       Styling
       Stateless Components
Resources


Project Source

For reference, the source code for this project can be viewed and downloaded here.

Introduction

During my first week at Theodo, I had a lot to learn about the main technologies used within the company. I focused my attention on learning to build a simple React Native application using Typescript and Redux. This post is aimed at those with a little knowledge of these technologies, guiding you from environment setup, to having a simple working Todos app! I should reiterate that some React, React Native, Typescript and Redux knowledge is assumed. Check out the Resources section for some useful beginner guides!

Environment Setup

The bane of a developer’s life is often related to setting up a working environment for your development. I’m going to outline the steps that I took to fully set up my development environment for this little project. I’ll also be writing this from a Mac OS perspective, but with the resources provided, I’m sure Unix/Windows translation won’t be too difficult!

Technologies

Homebrew

I try to install all the technologies that I need into a central location. This makes using homebrew - a very well maintained package manager for Mac OS - a natural choice.

To install, open a terminal and type:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Node Version Manager

Though this isn’t completely necessary, I like to install Node version manager so that I can have multiple easily manageable versions of Node installed on my Mac at once.

To install:

  1. Open a terminal and type brew install nvm
  2. Create NVMs working directory with mkdir ~/.nvm
  3. Open (or create) your ~/.profile (or ~/.zprofile if using zsh instead of bash) and add:

    export NVM_DIR="$HOME/.nvm"
    [ -s "$(brew --prefix)/opt/nvm/nvm.sh" ] && . "$(brew --prefix)/opt/nvm/nvm.sh" # This loads nvm
    [ -s "$(brew --prefix)/opt/nvm/etc/bash_completion.d/nvm" ] && . "$(brew --prefix)/opt/nvm/etc/bash_completion.d/nvm" # This loads nvm bash_completion
  4. Now every time you log in to your mac, your .profile (or .zprofile) will load NVM and its bash (or zsh) completion. Instead of logging out and logging in, we can invoke this file by running (replace .profile with .zprofile if using zsh) . ~/.profile in your terminal.

Make sure that NVM has been installed properly by typing nvm -v in your terminal.

Note: You can also place this last section in .bashrc (or .zshrc), but .bashrc (or .zshrc) is invoked every time a terminal window is opened. We only need to load NVM once, so we may as well just do it when we login by placing the code in .profile (or .zprofile)!


Node & NPM

We can install Node and NPM using NVM from the last step. Simply run these two commands in a terminal to install and use the latest version of Node (comes with NPM):

  1. nvm install node
  2. nvm use node
  3. Check the installation worked using node -v in a terminal window.

React Native CLI

React Native command-line interface makes it easy to create a new React Native application.

  1. Head over to the React Native setup guide.
  2. Select the ‘React Native CLI Quickstart’ tab.
  3. Do not install Node using homebrew (you should already have it through NVM)!
  4. Install watchman using homebrew.
  5. Follow the ‘Installing dependencies’ steps for both Target OS’s.

Text Editor

You can use whichever text editor you like, but I am using Visual Studio Code, which I highly recommend as it's very customisable!

Here is a list of the extensions that I use:

Many of these are configurable and there are lots of resources online for customisation!

The Todos App

Now that we have all of the necessary technologies installed, let’s make a React Native todos app!

Creating The App

Using the React Native CLI, we can easily create a React Native app from our terminal. Navigate to a directory where you’d like to store the app, then run:

npx react-native init *AwesomeTSProject* --template react-native-template-typescript

You can replace AwesomeTSProject with whatever project name you like. We are also using the Typescript template for our React Native app.

Note: npx will access the current version of React Native CLI at runtime so that you don’t have to install and manage a global version!

Next, navigate into your project directory and run Metro, a javascript bundler that ships with react native:

cd AwesomeTSProject
npx react-native start

Then run your application on iOS (or for android, replace run-ios with run-android):

npx react-native run-ios

Note: React Native version 0.63.4 is unable to install the most recent version of a debugging tool called Flipper on iOS. If you are running into errors involving this module, navigate to /ios/Podfile and replace use_flipper! with use_flipper!({ 'Flipper-Folly' => '2.3.0' }). Then delete the Podfile.lock and, in a terminal, navigate to the /ios directory and run pod install. Now it should be fixed!


Installing Icons

In order to use icon fonts in a React Native app, they must be installed. I use react-native-vector-icons from NPM.

Android Installation

Go here and follow the recommended installation instructions.

iOS Installation

  1. Open Xcode and open the ProjectName/ios/ProjectName.xcodeproj file.
  2. Follow these (manual) instructions
  3. You may need to run pod install in the ios directory before restarting your application.

Folder Structure

file structure

I have created a src directory containing all of the source code for my application. The first step is simply to move App.tsx inside this directory and update the import in index.js.

Each of the remaining folders inside src are as follows:

  • components - all the React components that build up a page live inside this folder (e.g. custom buttons and inputs.
  • config - all the files for configuration live here (e.g. default styles, colours)
  • screens - all the screens for the application live here. They are React components that compose many components from the components directory. (Note: there’s only one screen in this application)
  • store - all things Redux are stored here. Each folder within store denotes a feature. Each feature folder can contain types, actions, selectors and reducers.

I urge you to create these folders now! Don’t worry about the files, we’ll get to those later.


Designing Components

First, I like to think about the smallest components that I’ll need in my application and then build up. We’ll start with a text component.

Although React Native already supplies a Text component, I like to create an AppText component that encapsulates the default styles for my text. This way, we don’t have to repeat any text styling. Simply create a new AppText.tsx file in the components folder and look at the following code.

import React, { FunctionComponent } from "react";
import { Text, TextStyle } from "react-native";

import defaultStyles from "../config/styles";

interface Props {
  style?: TextStyle;
}

const AppText: FunctionComponent<Props> = ({ children, style }) => {
  return <Text style={[defaultStyles.text, style]}>{children}</Text>;
};

export default AppText;

/src/components/AppText.tsx

Just like in React, we create a functional AppText component, passing in its destructured props. Notice that props are typed using an interface (or type) containing all of the passed props. This interface (or type) is then passed to the generic type of the function component. The children prop comes from the FunctionComponent itself. We can also pass optional styles as a prop when using the AppText component, which has the same type as styles that you'd apply on a React Native Text component.

Styling

Styling a component works by setting its style prop to a style object. This can be inline, but it is good practice to create a stylesheet where each key is a separate style object. The style prop can also be given an array of style objects, where the last style object will take precedence if there are any conflicting rules (much like CSS!).

Any component that can be styled, follows the Flexbox styling routine.

Notice that we are using are defaultStyles.text as the first style for the text component. This is imported from ../config/styles. Let’s go and create that file now.

import { Platform, StyleSheet } from "react-native";

import colors from "./colors";

export default StyleSheet.create({
  text: {
    color: colors.dark,
    fontSize: 18,
    fontFamily: Platform.OS === "android" ? "Roboto" : "Avenir",
    fontWeight: "700",
  },
});

/src/config/styles.ts

This file simply exports a StyleSheet object, which can be imported anywhere in the app! Notice how it uses the colors module. This is another configuration file which is just an object storing your colour names.

const colors = {
  black: "#000",
  white: "#fff",
  red: "#de6e66",
  green: "#8bc989",
  light: "#f0f0f0",
  medium: "#6b6b6b",
  dark: "#0c0c0c",
};

export default colors;

/src/config/colors.ts

Now we can test our component works by navigating to src/App.tsx and replacing the code with the following.

import React, { FC } from "react";
import { SafeAreaView, StyleSheet } from "react-native";

import AppText from "./components/AppText";
import colors from "./config/colors";

const App: FC = () => {
  return (
    <SafeAreaView style={styles.container}>
      <AppText style={styles.text} />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    alignItems: "center",
    backgroundColor: colors.light,
    flex: 1,
    padding: 20,
  },
  text: {
    color: colors.red,
  },
});

/src/App.tsx

test

result


Stateless Components

Now that you know the basics of building stateless components, try building these components yourself. Take a look at my source code if you get stuck!

buttonpic

Button.tsx

textinputpic

AppTextInput.tsx

cardpic

Card.tsx


Before we move on to Redux, it’s worth taking a look at the /src/components/Screen.tsx component. This component encapsulates some logic to ensure that all content in the application is within the safe area of the screen (not underneath the notch). It also adds padding equal to the height of the status bar if we are using Android. We will use this component in the top level of our todos screen in the screens directory.

Part 2: Redux and Stateful Components

Now you're ready to move on to looking at integrating Redux into your Todos app, as well as adding some stateful components!

Click here for Part 2!

Resources

Benjamin Gowers

Benjamin Gowers

Web Developer at Theodo