The React Native Guide I Wish I Had! - Part 1: Environment and Stateless Components
Benjamin Gowers9 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:
-
Open a terminal and type
brew install nvm
-
Create NVMs working directory with
mkdir ~/.nvm
-
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
-
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):
nvm install node
nvm use node
- 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.
- Head over to the React Native setup guide.
- Select the ‘React Native CLI Quickstart’ tab.
- Do not install Node using homebrew (you should already have it through NVM)!
- Install watchman using homebrew.
- 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:
- Auto Close Tag
- Auto Import
- Auto Rename Tag
- Bracket Pair Colorizer 2
- ES7 React/Redux/GraphQL/React-Native snippets
- ESLint
- Highlight Matching Tag
- Prettier - Code formatter
- React Native Tools
- Sort-imports
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
- Open Xcode and open the ProjectName/ios/ProjectName.xcodeproj file.
- Follow these (manual) instructions
- You may need to run pod install in the ios directory before restarting your application.
Folder 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 thecomponents
directory. (Note: there’s only one screen in this application)store
- all things Redux are stored here. Each folder withinstore
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
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!
Button.tsx
AppTextInput.tsx
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!
Resources
- React Tutorial - useful for learning React!
- React Hooks - if you don’t know what react hooks are or how to use them, the official docs are great!
- React Native Basics - useful for learning React Native!
- Redux Essentials and Redux with React - both on the redux official docs, great source of information for redux newbies!
- Typescript in 5 mins! - learn the basics of Typescript!