Open In App

How to Create ToDo App using React Native ?

Last Updated : 01 Jun, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In this article, we'll see how to create a To-Do app using React Native. An ideal illustration of a basic application that can be developed with React Native is a To-Do app. This app enables users to generate, modify, and remove tasks, assisting them in maintaining organization and concentration.

How-to-Create-To-do-App

To give you a better idea of what we’re going to create, let’s watch a demo video.

Demo Video

Playground

Note: This Section is to interact with the app which you are going to build.

Prerequisites

Step-by-Step Implementation

Step 1: Create a React Native Project

Now, create a project with the following command.

npx create-expo-app app-name --template

Note: Replace the app-name with your app name for example : react-native-demo-app

Next, you might be asked to choose a template. Select one based on your preference as shown in the image below. I am selecting the blank template because it will generate a minimal app, as clean as an empty canvas in JavaScript.

It completes the project creation and displays a message: "Your Project is ready!" as shown in the image below.

Now go into your project folder, i.e., react-native-demo

cd app-name

Project Structure:

Step 2: Run  Application

Start the server by using the following command.

npx expo start

Then, the application will display a QR code.

  • For the Android users,
    • For the Android Emulator, press " a" as mentioned in the image below.
    • For the Physical Device, download the " Expo Go " app from the Play Store. Open the app, and you will see a button labeled " Scan QR Code. " Click that button and scan the QR code; it will automatically build the Android app on your device.
  • For iOS users, simply scan the QR code using the Camera app .
  • If you're using a web browser, it will provide a local host link that you can use as mentioned in the image below.

Step 3: Start Coding

- Approach: 

To develop a React Native todo application, it is crucial to adhere to a systematic method. Commence by specifying the features and functionalities of the app, encompassing tasks like adding, modifying, and removing items. Outline the architecture and data flow of the app, determining the required components and their interactions. Explore options for managing the app's state using React hooks or a state management library, and select a suitable data storage solution for preserving tasks. Design the user interface by breaking it down into reusable components, and incorporate navigation if necessary. Conduct comprehensive testing, including unit tests for critical functions and components, as well as user testing for obtaining feedback on usability.

- Import libraries:

Import required libraries at the top of the file.

JavaScript
import { useState } from "react"; // Importing useState hook from React
import {
  View,         // Importing View component for layout
  Text,       // Importing Text component for displaying text
  TextInput,    // Importing TextInput component for user input
  TouchableOpacity, // Importing TouchableOpacity for button-like behavior
  FlatList,    // Importing FlatList for rendering lists
  StyleSheet,   // Importing StyleSheet for styling components
} from "react-native"; // Importing necessary components from React Native


- StyleSheet:

Create a StyleSheet to style components like container, title, heading, input, addButton, addButtonText, task, itemList, taskButton, editButton and deleteButton.

JavaScript
// Styles for the components
const styles = StyleSheet.create({
  container: {
    flex: 1, // Take full screen height
    padding: 40, // Add padding around the container
    marginTop: 40, // Add margin at the top
  },
  title: {
    fontSize: 24, // Font size for the title
    fontWeight: "bold", // Bold font
    marginBottom: 20, // Margin below the title
  },
  heading: {
    fontSize: 30, // Font size for the heading
    fontWeight: "bold", // Bold font
    marginBottom: 7, // Margin below the heading
    color: "green", // Green color for the heading
  },
  input: {
    borderWidth: 3, // Border width for the input field
    borderColor: "#ccc", // Border color
    padding: 10, // Padding inside the input field
    marginBottom: 10, // Margin below the input field
    borderRadius: 10, // Rounded corners
    fontSize: 18, // Font size for the input text
  },
  addButton: {
    backgroundColor: "green", // Background color for the button
    padding: 10, // Padding inside the button
    borderRadius: 5, // Rounded corners
    marginBottom: 10, // Margin below the button
  },
  addButtonText: {
    color: "white", // Text color
    fontWeight: "bold", // Bold font
    textAlign: "center", // Center align the text
    fontSize: 18, // Font size for the button text
  },
  task: {
    flexDirection: "row", // Arrange items in a row
    justifyContent: "space-between", // Space between items
    alignItems: "center", // Align items vertically in the center
    marginBottom: 15, // Margin below each task
    fontSize: 18, // Font size for the task text
  },
  itemList: {
    fontSize: 19, // Font size for the task text
  },
  taskButtons: {
    flexDirection: "row", // Arrange buttons in a row
  },
  editButton: {
    marginRight: 10, // Margin to the right of the edit button
    color: "green", // Green color for the edit button text
    fontWeight: "bold", // Bold font
    fontSize: 18, // Font size for the edit button text
  },
  deleteButton: {
    color: "red", // Red color for the delete button text
    fontWeight: "bold", // Bold font
    fontSize: 18, // Font size for the delete button text
  },
});


- Main UI:

Below is the code for the Main UI, which contains components like a

  • TextInput : To take input from the user
  • TouchableOpacity: Buttons for Add, Update, and Delete tasks
  • Text: Used to display the text on the screen.
  • FlatList : Used to display a list of tasks.
JavaScript
<View style={styles.container}>
      <Text style={styles.heading}>Geeksforgeeks</Text> {/* App heading */}
      <Text style={styles.title}>ToDo App</Text> {/* App title */}
      <TextInput
        style={styles.input}
        placeholder="Enter task" // Placeholder text for the input field
        value={task} // Bind input value to task state
        onChangeText={(text) => setTask(text)} // Update task state on text change
      />
      <TouchableOpacity
        style={styles.addButton}
        onPress={handleAddTask} // Call handleAddTask on button press
      >
        <Text style={styles.addButtonText}>
          {editIndex !== -1 ? "Update Task" : "Add Task"} {/* Button text changes based on edit mode */}
        </Text>
      </TouchableOpacity>
      <FlatList
        data={tasks} // Pass tasks array as data
        renderItem={renderItem} // Render each task using renderItem
        keyExtractor={(_item, index) => index.toString()} // Unique key for each item
      />
</View>


- renderItem:

Function to render each task item.

JavaScript
const renderItem = ({ item, index }) => (
    <View style={styles.task}>
      <Text style={styles.itemList}>{item + " "}</Text> {/* Display the task */}
      <View style={styles.taskButtons}>
        <TouchableOpacity onPress={() => handleEditTask(index)}>
          <Text style={styles.editButton}>Edit</Text> {/* Edit button */}
        </TouchableOpacity>
        <TouchableOpacity onPress={() => handleDeleteTask(index)}>
          <Text style={styles.deleteButton}>Delete</Text> {/* Delete button */}
        </TouchableOpacity>
      </View>
    </View>
);


- handleAddTask:

Function to handle adding or updating a task.

JavaScript
const handleAddTask = () => {
    if (task) {
      if (editIndex !== -1) {
        // If editIndex is not -1, update the existing task
        const updatedTasks = [...tasks];
        updatedTasks[editIndex] = task; // Update the task at the specified index
        setTasks(updatedTasks); // Update the tasks state
        setEditIndex(-1); // Reset editIndex
      } else {
        // If editIndex is -1, add a new task
        setTasks([...tasks, task]); // Add the new task to the tasks array
      }
      setTask(""); // Clear the input field
    }
  };


- handleEditTask:

Function to handle editing a task.

JavaScript
const handleEditTask = (index) => {
    const taskToEdit = tasks[index]; // Get the task to be edited
    setTask(taskToEdit); // Set the task in the input field
    setEditIndex(index); // Set the index of the task being edited
};


- handleDeleteTask:

Function to handle deleting a task.

JavaScript
const handleDeleteTask = (index) => {
    const updatedTasks = [...tasks];
    updatedTasks.splice(index, 1); // Remove the task at the specified index
    setTasks(updatedTasks); // Update the tasks state
};


- useState:

useState is used to manage the state of the task input, list of tasks, and index of the task being edited.

JavaScript
// State to store the current task input
const [task, setTask] = useState("");
// State to store the list of tasks
const [tasks, setTasks] = useState([]);
// State to track the index of the task being edited
const [editIndex, setEditIndex] = useState(-1);

Complete Source Code

App.js:

App.js
import { useState } from "react"; // Importing useState hook from React
import {
  View,         // Importing View component for layout
  Text,       // Importing Text component for displaying text
  TextInput,    // Importing TextInput component for user input
  TouchableOpacity, // Importing TouchableOpacity for button-like behavior
  FlatList,    // Importing FlatList for rendering lists
  StyleSheet,   // Importing StyleSheet for styling components
} from "react-native"; // Importing necessary components from React Native

// Main App component
const App = () => {
  // State to store the current task input
  const [task, setTask] = useState("");
  // State to store the list of tasks
  const [tasks, setTasks] = useState([]);
  // State to track the index of the task being edited
  const [editIndex, setEditIndex] = useState(-1);

  // Function to handle adding or updating a task
  const handleAddTask = () => {
    if (task) {
      if (editIndex !== -1) {
        // If editIndex is not -1, update the existing task
        const updatedTasks = [...tasks];
        updatedTasks[editIndex] = task; // Update the task at the specified index
        setTasks(updatedTasks); // Update the tasks state
        setEditIndex(-1); // Reset editIndex
      } else {
        // If editIndex is -1, add a new task
        setTasks([...tasks, task]); // Add the new task to the tasks array
      }
      setTask(""); // Clear the input field
    }
  };

  // Function to handle editing a task
  const handleEditTask = (index) => {
    const taskToEdit = tasks[index]; // Get the task to be edited
    setTask(taskToEdit); // Set the task in the input field
    setEditIndex(index); // Set the index of the task being edited
  };

  // Function to handle deleting a task
  const handleDeleteTask = (index) => {
    const updatedTasks = [...tasks];
    updatedTasks.splice(index, 1); // Remove the task at the specified index
    setTasks(updatedTasks); // Update the tasks state
  };

  // Function to render each task item
  const renderItem = ({ item, index }) => (
    <View style={styles.task}>
      <Text style={styles.itemList}>{item + " "}</Text> {/* Display the task */}
      <View style={styles.taskButtons}>
        <TouchableOpacity onPress={() => handleEditTask(index)}>
          <Text style={styles.editButton}>Edit</Text> {/* Edit button */}
        </TouchableOpacity>
        <TouchableOpacity onPress={() => handleDeleteTask(index)}>
          <Text style={styles.deleteButton}>Delete</Text> {/* Delete button */}
        </TouchableOpacity>
      </View>
    </View>
  );

  // Main UI rendering
  return (
    <View style={styles.container}>
      <Text style={styles.heading}>Geeksforgeeks</Text> {/* App heading */}
      <Text style={styles.title}>ToDo App</Text> {/* App title */}
      <TextInput
        style={styles.input}
        placeholder="Enter task" // Placeholder text for the input field
        value={task} // Bind input value to task state
        onChangeText={(text) => setTask(text)} // Update task state on text change
      />

      <TouchableOpacity
        style={styles.addButton}
        onPress={handleAddTask} // Call handleAddTask on button press
      >
        <Text style={styles.addButtonText}>
          {editIndex !== -1 ? "Update Task" : "Add Task"} {/* Button text changes based on edit mode */}
        </Text>
      </TouchableOpacity>

      <FlatList
        data={tasks} // Pass tasks array as data
        renderItem={renderItem} // Render each task using renderItem
        keyExtractor={(_item, index) => index.toString()} // Unique key for each item
      />
    </View>
  );
};

// Styles for the components
const styles = StyleSheet.create({
  container: {
    flex: 1, // Take full screen height
    padding: 40, // Add padding around the container
    marginTop: 40, // Add margin at the top
  },
  title: {
    fontSize: 24, // Font size for the title
    fontWeight: "bold", // Bold font
    marginBottom: 20, // Margin below the title
  },
  heading: {
    fontSize: 30, // Font size for the heading
    fontWeight: "bold", // Bold font
    marginBottom: 7, // Margin below the heading
    color: "green", // Green color for the heading
  },
  input: {
    borderWidth: 3, // Border width for the input field
    borderColor: "#ccc", // Border color
    padding: 10, // Padding inside the input field
    marginBottom: 10, // Margin below the input field
    borderRadius: 10, // Rounded corners
    fontSize: 18, // Font size for the input text
  },
  addButton: {
    backgroundColor: "green", // Background color for the button
    padding: 10, // Padding inside the button
    borderRadius: 5, // Rounded corners
    marginBottom: 10, // Margin below the button
  },
  addButtonText: {
    color: "white", // Text color
    fontWeight: "bold", // Bold font
    textAlign: "center", // Center align the text
    fontSize: 18, // Font size for the button text
  },
  task: {
    flexDirection: "row", // Arrange items in a row
    justifyContent: "space-between", // Space between items
    alignItems: "center", // Align items vertically in the center
    marginBottom: 15, // Margin below each task
    fontSize: 18, // Font size for the task text
  },
  itemList: {
    fontSize: 19, // Font size for the task text
  },
  taskButtons: {
    flexDirection: "row", // Arrange buttons in a row
  },
  editButton: {
    marginRight: 10, // Margin to the right of the edit button
    color: "green", // Green color for the edit button text
    fontWeight: "bold", // Bold font
    fontSize: 18, // Font size for the edit button text
  },
  deleteButton: {
    color: "red", // Red color for the delete button text
    fontWeight: "bold", // Bold font
    fontSize: 18, // Font size for the delete button text
  },
});

// Export the App component as the default export
export default App;

Output:


Next Article

Similar Reads