Open In App

Create a Task Manager App using React-Native

Last Updated : 06 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we’ll walk you through the process of building a basic Task Manager app using React Native. The application enables users to effortlessly create, edit, complete/incomplete, and delete­ tasks, providing an uncomplicated yet impactful introduction to Re­act Native’s mobile app development capabilities.

Prerequisites

Steps to install & configure React Native

Step 1: Create a react native application by using this command:

npx create-expo-app taskmanager-app

Step 2: After creating your project folder, i.e. taskmanager-app, use the following command to navigate to it:

cd taskmanager-app

Step 2: Use an external library for a Date Picker

In this App, we have installed react native modern date picker for selecting dates.

npm i react-native-modern-datepicker

Project structure

Screenshot-from-2023-09-27-10-24-05

Approach

This code snippe­t in React Native allows you to build a simple taskmanager app effortlessly. It effe­ctively manages the state­ using useState, enabling you to handle­ task data, editing functionality, and modal visibility smoothly. The app’s inte­rface presents a scrollable­ list of tasks, each featuring a title­. By utilizing modals with title and content inputs, users can e­asily add, edit,complete/incomplete and delete­ tasks.

Example: This example creates a Task Manager App using react-native

Javascript




// App.js
  
// Import necessary modules and components
import React, { useState } from "react";
import {
    View,
    Text,
    TouchableOpacity,
    Modal,
    Button,
} from "react-native";
  
// Import TaskList component
import TaskList from "./components/TaskList"
  
// Import TaskModal component
import TaskModal from "./components/TaskModel"
import styles from "./styles"; // Import styles
  
// Define the main App component
const App = () => {
    // Define state variables
      
    // Array to store tasks
    const [tasks, setTasks] = useState([]); 
    const [task, setTask] = useState({
        title: "",
        description: "",
        status: "Pending",
        deadline: "",
        createdAt: "",
    }); 
      
    // Task object for creating/editing tasks
      
    // Modal visibility
    const [modalVisible, setModalVisible] = useState(false); 
      
    // Task being edited
    const [editingTask, setEditingTask] = useState(null); 
    const [validationError, setValidationError] =
        useState(false); // Validation flag
  
    // Function to add a new task or update an existing task
    const handleAddTask = () => {
        if (
            task.title.trim() !== "" &&
            task.deadline !== ""
        ) {
            const currentDate = new Date();
            const formattedDate =
                currentDate.toLocaleString();
  
            if (editingTask) {
              
                // If editing an existing task, update it
                const updatedTasks = tasks.map((t) =>
                    t.id === editingTask.id
                        ? { ...t, ...task }
                        : t
                );
                setTasks(updatedTasks);
                setEditingTask(null);
            } else {
              
                // If adding a new task, create it
                const newTask = {
                    id: Date.now(),
                    ...task,
                      
                    // Set the creation date and time as a string
                    createdAt: formattedDate, 
                };
                setTasks([...tasks, newTask]);
            }
  
            // Clear the task input fields and reset state
            setTask({
                title: "",
                description: "",
                status: "Pending",
                deadline: "",
                createdAt: "",
            });
              
            // Close the modal
            setModalVisible(false);
              
            // Reset validation error
            setValidationError(false); 
        } else {
          
            // Show validation error if fields are not filled
            setValidationError(true); 
        }
    };
  
    // Function to handle task editing
    const handleEditTask = (task) => {
      
        // Set the task being edited
        setEditingTask(task); 
          
        // Pre-fill the input with task data
        setTask(task); 
          
        // Open the modal for editing
        setModalVisible(true); 
    };
  
    // Function to delete a task
    const handleDeleteTask = (taskId) => {
        const updatedTasks = tasks.filter(
            (t) => t.id !== taskId
        );
        setTasks(updatedTasks);
    };
  
    // Function to toggle task completion status
    const handleToggleCompletion = (taskId) => {
        const updatedTasks = tasks.map((t) =>
            t.id === taskId
                ? {
                      ...t,
                      status:
                          t.status === "Pending"
                              ? "Completed"
                              : "Pending",
                  }
                : t
        );
        setTasks(updatedTasks);
    };
  
    // Return the JSX for rendering the component
    return (
        <View style={styles.container}>
            <Text style={styles.title}>Task Manager</Text>
            {/* Render the TaskList component */}
            <TaskList
                tasks={tasks}
                handleEditTask={handleEditTask}
                handleToggleCompletion={
                    handleToggleCompletion
                }
                handleDeleteTask={handleDeleteTask}
            />
            {/* Button to add or edit tasks */}
            <TouchableOpacity
                style={styles.addButton}
                onPress={() => {
                    setEditingTask(null);
                    setTask({
                        title: "",
                        description: "",
                        status: "Pending",
                        deadline: "",
                        createdAt: "",
                    });
                    setModalVisible(true);
                    setValidationError(false);
                }}>
                <Text style={styles.addButtonText}>
                    {editingTask ? "Edit Task" : "Add Task"}
                </Text>
            </TouchableOpacity>
            {/* Render the TaskModal component */}
            <TaskModal
                modalVisible={modalVisible}
                task={task}
                setTask={setTask}
                handleAddTask={handleAddTask}
                handleCancel={() => {
                    setEditingTask(null);
                    setTask({
                        title: "",
                        description: "",
                        status: "Pending",
                        deadline: "",
                        createdAt: "",
                    });
                    setModalVisible(false);
                    setValidationError(false);
                }}
                validationError={validationError}/>
        </View>
    );
};
  
// Export the App component as the default export
export default App;


Javascript




// components/TaskList.js
import React from "react";
import { ScrollView } from "react-native";
import TaskItem from "./TaskItem";
import styles from "../styles";
  
const TaskList = ({
    tasks,
    handleEditTask,
    handleToggleCompletion,
    handleDeleteTask,
}) => {
    return (
        <ScrollView style={styles.taskList}>
          
            {/* Scrollable container for the list of tasks */}
            {tasks.map((t) => (
                <TaskItem
                    // Use the task's ID as the key to 
                    // uniquely identify each TaskItem
                    key={t.id}
                      
                    // Pass the task object as a prop to TaskItem
                    task={t}
                      
                    // Pass functions to handle editing, 
                    // toggling completion, and deletion
                    handleEditTask={handleEditTask}
                    handleToggleCompletion={
                        handleToggleCompletion
                    }
                    handleDeleteTask={handleDeleteTask}
                />
            ))}
        </ScrollView>
    );
};
// Export the TaskList component
export default TaskList;


Javascript




// components/TaskItem.js
import React from "react";
import { View, Text, TouchableOpacity } from "react-native";
import styles from "../styles";
  
const TaskItem = ({
    task,
    handleEditTask,
    handleToggleCompletion,
    handleDeleteTask,
}) => {
    return (
        <View style={styles.taskItem}>
            <View style={styles.taskTextContainer}>
                <Text
                    style={[
                        styles.taskText,
                        task.status === "Completed" &&
                            styles.completedTaskText,
                    ]}>
                    {task.title}
                </Text>
                <Text style={styles.taskDescription}>
                    {task.description}
                </Text>
                <Text style={styles.taskStatus}>
                    Status: {task.status}
                </Text>
                <Text style={styles.taskDeadline}>
                    Deadline: {task.deadline}
                </Text>
                <Text style={styles.taskCreatedAt}>
                    Created: {task.createdAt}
                </Text>
            </View>
            <View style={styles.buttonContainer}>
                <TouchableOpacity
                    onPress={() => handleEditTask(task)}
                    style={[styles.editButton]}>
                    <Text style={styles.buttonText}>
                        Edit
                    </Text>
                </TouchableOpacity>
                <TouchableOpacity
                    onPress={() =>
                        handleToggleCompletion(task.id)
                    }
                    style={[
                        styles.completeButton,
                        task.status === "Completed" &&
                            styles.completedButton,
                    ]}>
                    <Text style={styles.buttonText}>
                        {task.status === "Completed"
                            ? "Pending"
                            : "Completed"}
                    </Text>
                </TouchableOpacity>
                <TouchableOpacity
                    onPress={() =>
                        handleDeleteTask(task.id)
                    }
                    style={[styles.deleteButton]}>
                    <Text style={styles.buttonText}>
                        Delete
                    </Text>
                </TouchableOpacity>
            </View>
        </View>
    );
};
  
export default TaskItem;


Javascript




// components/TaskModal.js
import React from "react";
import {
    View,
    Text,
    TextInput,
    Button,
    Modal,
} from "react-native";
import styles from "../styles";
import DatePicker from "react-native-modern-datepicker";
  
const TaskModal = ({
    modalVisible,
    task,
    setTask,
    handleAddTask,
    handleCancel,
    validationError,
}) => {
    return (
        <Modal
            visible={modalVisible}
            animationType="slide"
            transparent={false}>
              
            {/* Container for the modal */}
            <View style={styles.modalContainer}>
                <TextInput
                    style={styles.input}
                    placeholder="Title"
                    value={task.title}
                    onChangeText={(text) =>
                        setTask({ ...task, title: text })
                    }
                    // Update the title when text changes/>
                      
                <TextInput
                    style={styles.input}
                    placeholder="Description"
                    value={task.description}
                    onChangeText={(text) =>
                        setTask({
                            ...task,
                            description: text,
                        })
                    }/>
                      
                <Text style={styles.inputLabel}>
                    Deadline:
                </Text>
                <DatePicker
                    style={styles.datePicker}
                    mode="date"
                    selected={task.deadline}
                    onDateChange={(date) =>
                        setTask({ ...task, deadline: date })
                    }/>
                      
                {validationError && (
                    <Text style={styles.errorText}>
                        Please fill in all fields correctly.
                    </Text>
                )}
                <Button
                  
                    // Display "Update" when editing an existing 
                    // task, "Add" when adding a new task
                    title={task.id ? "Update" : "Add"}
                    // Call the handleAddTask function 
                    // when the button is pressed
                    onPress={handleAddTask}
                    // Set the button color
                    color="#007BFF"/>
                      
                <Button
                    title="Cancel"
                    onPress={handleCancel}
                    color="#FF3B30"/>
            </View>
        </Modal>
    );
};
  
export default TaskModal;


Javascript




// styles.js
  
import { StyleSheet } from "react-native";
  
const styles = StyleSheet.create({
    container: {
        flex: 1,
        padding: 20,
        backgroundColor: "#f7f7f7",
    },
    title: {
        fontSize: 28,
        fontWeight: "bold",
        marginBottom: 20,
        color: "#333",
        textAlign: "center",
    },
    taskList: {
        flex: 1,
    },
    taskItem: {
        flexDirection: "row",
        justifyContent: "space-between",
        alignItems: "center",
        backgroundColor: "#fff",
        marginBottom: 10,
        padding: 15,
        borderRadius: 10,
    },
    taskTextContainer: {
        flex: 1,
    },
    taskText: {
        fontSize: 18,
        fontWeight: "bold",
        color: "#333",
    },
    completedTaskText: {
        textDecorationLine: "line-through",
        color: "gray",
    },
    taskDescription: {
        fontSize: 16,
        color: "#666",
    },
    taskTime: {
        fontSize: 14,
        color: "#666",
    },
    taskStatus: {
        fontSize: 16,
        color: "#666",
    },
    buttonContainer: {
        // Or 'row' depending on your layout
        flexDirection: "column"
        // Adjust the value as needed for the 
        // desired spacing
        marginVertical: 2, 
    },
  
    editButton: {
        backgroundColor: "#007BFF",
        borderRadius: 5,
        padding: 10,
        marginRight: 10,
        width: 110,
    },
    button: {
        marginBottom: 10,
    },
    completeButton: {
        backgroundColor: "#4CAF50",
        borderRadius: 5,
        padding: 10,
        marginRight: 10,
        width: 110,
    },
    completedButton: {
        backgroundColor: "#808080",
    },
    buttonText: {
        color: "#fff",
        fontSize: 15,
    },
    deleteButton: {
        backgroundColor: "#FF9500",
        borderRadius: 5,
        padding: 10,
        width: 110,
    },
    addButton: {
        alignItems: "center",
        justifyContent: "center",
        backgroundColor: "#007BFF",
        paddingVertical: 15,
        borderRadius: 10,
        marginTop: 20,
    },
    addButtonText: {
        color: "#fff",
        fontSize: 18,
        fontWeight: "bold",
    },
    modalContainer: {
        flex: 1,
        padding: 20,
        backgroundColor: "#fff",
    },
    input: {
        borderWidth: 1,
        borderColor: "#ccc",
        padding: 10,
        marginBottom: 20,
        borderRadius: 5,
        fontSize: 16,
    },
    inputLabel: {
        fontSize: 16,
        fontWeight: "bold",
    },
    errorText: {
        color: "#FF3B30",
        fontSize: 16,
        marginBottom: 10,
    },
    taskDeadline: {
        color: "#FF3B12",
    },
    taskCreatedAt: {
        color: "#5497FF",
    },
});
  
export default styles;


Steps to Run

Go to the Terminal and type the following command to run the react native application.

npx expo start

To run on Android:

npx react-native run-android

To run on iOS:

npx react-native run-ios

Output:

aaaaa



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads