Mobile ProgrammingLearn How to Build a React Native ToDo Application – Part 1

Learn How to Build a React Native ToDo Application – Part 1

React Native is a framework for building native mobile apps using Javascript. It uses the same design of React, giving a developer the power to compose a cross-platform mobile UI from declarative Javascript components.

React Native isn’t a WebView that renders HTML elements inside an app. With the help of which you can build mobile apps with native IOS/Android UI components. Behind the scenes, React Native is using a bridge between JavaScript and native platform specific components.

In this tutorial, we are going to build a Todo Application as our example using React Native. This mobile application will be cross-platform meaning it will run both on Android and iOS device. We will be using Expo XDE to generate the project. It will take care of all behind the scenes so that we can concentrate on building what is required.

By the end of this tutorial, you will observe working with:

React Native as a framework for developing cross-platform mobile applications
Using Expo as a tool for development
Using Expo as a client
How to change Statusbar
Using Platform Specific Code in a React Native app
Using ScrollView for scrollable Lists
Local State management
AsyncStorage for saving and fetching real-time data on the device’s disk
Lastly, how to build a todo application

This tutorial series is divided in three parts. In the first part, we will

Requirements

Before we get started, take a look at these requirements to start a React Native application on a local machine.

Node.js Installed
Expo XDE installed

Generating our Project Structure

Use Expo XDE to generate the project structure. It will help us to get started quickly. Open the XDE, enter the name of your project and click on create.
enter-project-name
When the XDE completes running React Native Package Manager and builds up the project, you can go to Device dropdown menu at the right and click on whichever simulator you have installed depending on the operations system you are using. Windows users please make sure you have android studio and necessary files installed and MacOS users, please have XCode installed or upto date.
open
You can also view the application, by running it using Expo Client on your mobile device. Note that, depending on your internet connection, this can be slow and your mobile device and development machine must be on same wifi connection. Scan the QR code in Share section, and you are ready to go. Once, the app is rendered, you will be welcomed by the default screen:
default screen
Now open your favorite text editor/IDE because we will be starting with the code in next section.
Getting Started
By default, the code in App.js looks like this:

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

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Open up App.js to start working on your app!</Text>
      </View>
    );
  }
}

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

We will start by changing the background color of our application.

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#f23657'
    // rest of the code remains same
  }
});

You can notice that the background color changes as soon as the app rebuilds.
background color

Changing the Status Bar Color

Also notice the status bar of our application, it does fit the picture. We will change it to white such that it is reflected beautifully. This can be done by importing StatusBar component from react-native. We will be using barStyle prop to change color. For only android devices, you can change the height of the status bar by using currentHeight prop. iOS does not allow this.

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

// rest of the code

return (
  <View style={styles.container}>
    <StatusBar barStyle="light-content" />
  </View>
);

Status Bar Color

Change Background to Gradient View and App Title

We will add the gradient view styling for background. Luckily, Expo provides a component just for that. As usual, we will start by import the component in our App.js file.

import { LinearGradient } from 'expo';

<LinearGradient style={styles.container} colors={['#DA4453', '#89216B']}>
  <StatusBar barStyle="light-content" />
  <Text>Open up App.js to start working on your app!</Text>
</LinearGradient>;

We will replace the View with the newly imported component. We will also add the title of our application by using Text component.

<Text style={styles.appTitle}>Minimalist Todo App</Text>

Add styles for app title and refactoring our container styles we get:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center'
    // justifyContent: 'center'
  },
  appTitle: {
    color: '#fff',
    fontSize: 36,
    marginTop: 60,
    marginBottom: 30,
    fontWeight: '300'
  }
});

Minimalist Todo App
For ideas on Gradient View combinations, you can visit uiGradients.com.

Adding a Card View

After adding title of our application, we are going to work on display a card view which look similar to a paper with rounded corners. All of this code will come below our app title.

<View style={styles.card}>
  <TextInput style={styles.input} placeholder="Add an item!" />
</View>

This card view will be responsible in showing an input value field from where the user will enter an item in their list. This card will then continue to display the rest of the list. We have to import TextInput component from react-native and with that will also import Dimensions.

Dimensions is a component that can help us to set the initial width and height of a component before the application runs. We will be using its get() method to acquire any device’s width and height. We will be using that acquired width for in our card. Just before, render() type:

const { heigh, width } = Dimensions.get('window');

For a to appear in react native on device screen, it always need a minimum height. They styles of the card view and text input looks like this:

card: {
    backgroundColor: '#fff',
    flex: 1,
    width: width - 25,
    borderTopLeftRadius: 10,
    borderTopRightRadius: 10
  },
  input: {
    padding: 20,
    borderBottomColor: '#bbb',
    borderBottomWidth: 1,
    fontSize: 24
  }

width in width – 25 is what we are getting from dimensions. borderTopLeftRadius and borderTopRightRadius are used simultaneously to provide rounded corners. After this step, here how our app looks:
borderTopLeftRadius

Adding Shadow

Adding shadow to any UI component is always platform specific in a React Native application. For iOS we have to use properties like: shadowOpacity, define a shadowColor, shadowRadius and shadowOffset. For android, the property to define a shadow effect we use is different. It is called `elevation it is what we need.

 card: {
    backgroundColor: '#fff',
    flex: 1,
    width: width - 25,
    borderTopLeftRadius: 10,
    borderTopRightRadius: 10,
    ...Platform.select({
      ios: {
        shadowColor: 'rgb(50,50,50)',
        shadowOpacity: 0.5,
        shadowRadius: 5,
        shadowOffset: {
          height: -1,
          width: 0
        }
      },
      android: {
        elevation: 5
      }
    })
  },

React Native provides a module called Platform that detects the platform in which the app is running. You can use the detection logic to implement platform-specific code for styling just like we did above or with any other component. To use Platform module, we have to import it from React Native.
Add-an-item

Adding a local State

We will now add a local state to our App component to keep track of any new input provided by the user in out application.

state = {
  newTodoItem: ''
};

Next we will define a controller function that will read the value from and update the local state.

newTodoItemController = textValue => {
  this.setState({
    newTodoItem: textValue
  });
};

Now we will update the in our render function.

<TextInput
  style={styles.input}
  placeholder={'Add an item!'}
  value={newTodoItem}
  onChangeText={this.newTodoItemController}
  placeholderTextColor={'#999'}
  returnKeyType={'done'}
  autoCorrect={false}
/>

Lots of new attributes are added. Let’s go through each of them one by one.

placeholder: just like in HTML, placeholder is to define a default message in the input field indicating as if what is expected.
placeholderTextColor: the custom text color of the placeholder string.
value: it is the value of the text input. By default it will be an empty string since we are using the local state to set it. As the state updates, its value of text input updates automatically.
onChangeText: it is a callback that is called when the text input’s text changes. Changed text is passed as an argument to the callback handler.
returnKeyType: determines how the return key on the device’s keyboard should look. You can find more values or platform specific values here.
autoCorrect: this prop let us decide whether to show the auto correct bar along with keyboard or not. In our case, we have set it to false.

After current step, this is how our app responds:
Todo-app-buy-milk

The ScrollView

The ScrollView component provided by React Native is the generic scrolling container that can host multiple other components and views. It work both ways, vertical by default and horizontal by setting the property. We will be using this component to display the list of todo items, just after the TextInput.

<ScrollView>
  <TodoList />
</ScrollView>

We will import the TodoList component from our components folder.

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

class TodoList extends Component {
  render() {
    return (
      <View>
        <Text>Todo List will show here</Text>
      </View>
    );
  }
}

export default TodoList;

Todo-list-will-show

Todolist UI

To begin creating the UI for our Todo List component we will start by defining a local state. This local state will have on property isEditing that will be useful later on to determine whether our list is in editing mode or not. After that, we are going to import desired components, some you are familiar with the previous section such as Dimensions, View and Text.

TouchableOpactiy is the new one here and it acts as a wrapper for making views respond properly to touches which is useful for any mobile or tablet device. Inside this component, we define our own styles to display a circle which will later act as button to check or un check the item from the list.

The text that holds the item will be shown next to the TouchableOpacity component.

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

const { height, width } = Dimensions.get('window');

class TodoList extends Component {
  state = {
    isEditing: false
  };

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity>
          <View style={styles.circle} />
        </TouchableOpacity>
        <Text style={styles.text}>Todo List will show here</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    width: width - 50,
    borderBottomColor: '#bbb',
    borderBottomWidth: StyleSheet.hairlineWidth,
    flexDirection: 'row',
    alignItems: 'center'
  },
  text: {
    fontWeight: '500',
    fontSize: 18,
    marginVertical: 20
  },
  circle: {
    width: 30,
    height: 30,
    borderRadius: 15,
    borderColor: 'red',
    borderWidth: 3,
    marginRight: 20
  }
});

export default TodoList;

To render it correctly in our ScrollView in App.js, we have to make changes in it. We have to add styling and ScrollView that is done by using a prop called contentContainerStyle which accepts our own custom style container as its value.

<ScrollView contentContainerStyle={styles.listContainer}>
  <TodoList />
</ScrollView>;

// Styles
listContainer: {
  alignItems: 'center';
}

Add-item-todo-list
We will continue to design the toggle when a user checks or un checks the item in the list. Start by adding another property to our local state in Todolist.js.

state = {
  isCompleted: false
};

We will also define a function called toggleComplete that will respond to the onPress action on TouchableOpacity in our view. This function is going to use prevState property provided by Reactjs to set the state.isCompleted. This way we do not have to recheck and define two different functions for the check and un check user action.

toggleItem = () => {
    this.setState(prevState => {
      return{
        isCompleted: !prevState.isCompleted
      }
    })
  }

<TouchableOpacity onPress={this.toggleItem}>

However, nothing happens yet. We have to add styles for the toggle of each item in the todo list. We can use the conditional operator in this case.

render() {
  const {isCompleted} = this.state;

  /* ... */

  <View style={[styles.circle, isCompleted ? styles.completeCircle : styles.incompleteCircle]}>

  </View>
}

// Styles
circle: {
    width: 30,
    height: 30,
    borderRadius: 15,
    // remove borderColor property from here
    borderWidth: 3,
    marginRight: 20
  },
  completeCircle: {
    borderColor: '#bbb'
  },
  incompleteCircle: {
    borderColor: '#DA4453'
  }

React Native allows passing of the styles in an array. This a common pattern you will be taking a look at a lot, in this application and other ones too when you have similar scenario of conditioning styles on the basis of state.

Similarly, we add styling on the Text element too.

<Text style={[styles.text, isCompleted ? styles.strikeText : styles.unstrikeText]}>
  Todo List will show here
</Text>

// Styles

strikeText: {
    color: '#bbb',
    textDecorationLine: 'line-through'
  },
  unstrikeText: {
    color: "#29323c"
  }

delete-todo-list
That’s it for part 1. In the next part we will continue to build our application by completing our UI and providing more functionality to component. For further knowledge continue reading our next tutorial.

1 COMMENT

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -