My ToDo’S

M

You will create a small ToDo application with React Native and more specially with Expo CLI. In this tutorial you will learn the basics of the React Native development. Application UI will be created with build-in React Native components and styles. Created project is tested with a emulator and a real device. To test with emulators you will need to install Android Studio or Xcode.

Purpose and learning process

In this exercise you will learn the basics of the React Native development:

  • using and rendering build-in components
  • creating and rendering an own components
  • understand state and props
  • event handling
  • passing data between components
  • calling functions between components
  • using styles

Example screenshots and video

User can add and remove a todo’s in this application.

Example video: https://youtu.be/mfgAYeNrn-8

Install node

You will need to install NodeJS before you can create React Native projects. You can find Node here: https://nodejs.org/en/download/.

Install Expo CLI

This tutorial will use Expo to create React Native application. You will need to install Expo CLI command line utility. You can follow these instructions Expo Getting Started or command below.

npm install -g expo-cli

Create a new project

Create a new React Native project called “ToDo”

expo init ToDo

Now you can select “blank – a minimal app as clean as empty canvas” Git repository will be created and all needed dependecies will be installed.

Run project

To get started go to your project folder and start development server.

cd ToDo
npm start

You can also use: expo start. This will start a development server for you.

Now your development server should be running and ready:

Run app on Expo client in your mobile

Install Expo client app to your iOS or Android phone and connect it to same wireless network as your computer. On Android, use Expo app to scan the QR code to open your project. On iOS, use camera app to scan QR code to open Expo app.

Your app should be running in mobile phone’s Expo application.

Run app on Android or iOS emulator

Use Android Studio or Xcode to launch emulator first and click “Run on Android device/emulator” or “Run on iOS simulator” buttons to launch application to emulator/simulator. You can download Android Studio here: Download Android Studio. Read more information about Xcode here: Xcode.

Remember, you will need to install Expo client to your emulator/simulator.

Modify App.js

Open App.js in text editor and edit displayed text line to show “Hello React Native!” text.

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello React Native!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

The application should reload automatically once you have saved your changes.

One good editor is Visual Studio Code, download it from here: Visual Studio Code.

Add a new component to the app

React Native provides a number of built-in components which can be used in applications. Of course, you can create your own components too.

Create a Banner component, which will be used at the top of the ToDo app. Add a following code before App function. So, you can use multiple components in the same file. Of course, you should separate all the components to different files, if your project get’s bigger.

class Banner extends React.Component {
  render() {
    return (
      <View style={styles.banner}>
        <Text style={styles.bannerText}>ToDo example with React Native</Text>
      </View>
    );
  }
}

Above code creates a new Banner React component, which only renders a “ToDo example with React Native” text with build-in Text component. Next remove Text component, which displays “Hello React Native!” text and use Banner component.

export default function App() {
  return (
    <View style={styles.container}>
      <Banner />
    </View>
  );
}

Modify a container style and add a new style for the Banner.

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 25,
    margin: 5
  }, 
  banner: {
    backgroundColor: 'cadetblue',
    justifyContent: 'center',
    marginBottom: 20
  },
  bannerText: {
    color: 'white',
    textAlign: 'center',
    paddingTop: 20,
    paddingBottom: 20
  }
});

Now a Banner component should be visible at the top of the application.

Add a new ToDo to the List

A new todo will be asked with a build-in TextInput component and all ToDo items will be displayed with an own made component in a ScrollView. Create a new ToDoList component with a below code.

class ToDoList extends React.Component {
  render() {
    return (
      <View>
        <View style={styles.addToDo}>
          <TextInput style={styles.addToDoTextInput} />
          <Button title="Add" />
        </View>
        <ScrollView style={styles.list}>
          <Text>* First</Text>
          <Text>* Second</Text>
        </ScrollView>   
      </View>
    );
  }
}

Now only a few hardcoded strings will be displayed in ScrollView. Remember import TextInput, Button and ScrollView components (modify import line at the top of the code).

import { 
  StyleSheet, 
  Text, 
  View, 
  TextInput, 
  Button, 
  ScrollView 
} from 'react-native';

Use/add following styles to show TextInput and Button components side by side.

addToDo: {
  flexDirection: 'row',
  marginBottom: 20,
},
addToDoTextInput : {
  borderWidth: 1,
  borderStyle: 'solid',
  borderColor: '#ccc',
  padding: 5,
  margin: 2,
  flex: 1,
},
list: {
  color: 'black',
  margin: 2,
},

Remember add ToDoList component to App function rendering

<View style={styles.container}>
    <Banner />
    <ToDoList />
</View>

You should see TodoList below Banner.

ToDoList component should hold all the ToDo items in an array and a new item text. All these data should be saved in states, so you need to initialize these in your component constructor.

Add a following code inside ToDoList component.

constructor(props) {
  super(props);
  this.state = { items: [], text: '' };
}

Easiest way to get TextInput component’s text is to listen TextInput’s onChangeText event and store changes to text state. Modify a following code inside TextInput element.

<TextInput 
  style={styles.addToDoTextInput}
  onChangeText={(text) => this.setState({text})}
  value={this.state.text}/>

Now the value of TextInput component will be stored into text state variable.

A new ToDo item should be added to the items array, when user taps the Button component. Modify Button component code as shown in below.

<Button 
  title="Add" style={styles.addTodoButton}
  onPress={this.addToDoItem}/>

Create addTodoItem function, which will be called, when the button is tapped. Add a following code inside ToDoList component.

addToDoItem = () => {
  if (this.state.text !== '') {
    this.setState({
      items: [...this.state.items, this.state.text],
      text: ''
    });
    Keyboard.dismiss();
  }
}

Above code check’s that text is not empty and then add a new text to items collection. Keyboard will be dismissed, remember import Keyboard class too!

Next ToDo items need to be rendered inside a ScrollView. For this purpose, create a new component called ListItem. Create a new ListItem component as show in below code.

class ListItem extends React.Component {
  render() {
    return (
      <View style={styles.listItem}>
        <Text style={styles.listItemText}>* {this.props.text}</Text>
        <Text style={styles.listItemDelete}>X</Text>
      </View>
    )
  }
}

This component will show the new todo item text and X char, which will be used later to delete a todo. Remember add a new styles for these items too.

listItem: {
  flex: 1, 
  flexDirection: 'row',
  margin: 5
},
listItemText: {
},
listItemDelete: {
  marginStart: 10,
  color: 'red',
  fontWeight: 'bold'
}

Now ListItem component is ready and it can display a ToDo item. Modify ToDoList renderer to loop through all ToDo items and create ListItem components. Add a following code inside a render function, but before return clause.

var items = this.state.items.map(function(item,index){
  return (
    <ListItem text={item} key={index} index={index} />
  )
});

Above code will loop through all the items inside items array and create a ListItem components.

Modify a render function to show these items.

<ScrollView style={styles.list}>
  {items}
</ScrollView>

Testing

Try to add a few Todo items in your app. It should work now!

Remove a Todo

Last step in this tutorial is to add a remove a todo item functionality.

Modify a Text component (which displays X char) to handle onPress event, which will be call deleteTodoItem function.

<Text style={styles.listItemDelete} 
  onPress={(e) => this.deleteToDoItem(this.props.index)}>X</Text>

Add a deleteTodoItem function inside ListItem component.

deleteToDoItem = (index) => {
  this.props.deleteToDoItem(index);
}

Now deleteToDoItem are inside a ListItem componenent and it needs to call the parent component to delete this item from the items array. This can be done using a props. Modify ToDoList component to pass this prop function call and add the function.

Modify LisItem component to pass function inside props.

<ListItem text={item} key={index} index={index} 
  deleteToDoItem={this.deleteToDoItem}/>

And add a deleteToDoItem function inside ToDoList component:

deleteToDoItem = (index) => {
  var items = this.state.items;
  items.splice(index, 1);
  this.setState({items:items});
}

Testing

Try to run your code and add/remove a new item. You should get a following error message:

This happens, because this is undefined inside a ListItem creating scope. You need to modify ListItem creation inside ToDoList component. This can be done with binding this inside a map looping process. So, deleteTodoItem can be found inside a ToDoList component.

var items = this.state.items.map(function(item,index){
  return (
    <ListItem text={item} key={index} index={index} 
      deleteToDoItem={this.deleteToDoItem}/>
  )
}.bind(this));

TEsting

Your app should be ready now.

Add comment

Pasi Manninen

Pasi Manninen

Pasi is a mobile and web application developer. Currently working as a senior lecturer in JAMK University of Applied Sciences. Pasi has programming experience over many decades and has taught dozens of courses since the 90's.

Recent Posts

Follow Me