Create a Task Manager App using React-Native

Last Updated : 25 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
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.

Create-a--Task-Manager--App-using


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

Demo Video

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: File Structure

Follow the file structure below to ensure better code organization.

File_structure

Step 4: Start Coding

Approach

This code snippe­t in React Native allows you to build a simple task manager 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

App.js
// App.js

// Import necessary modules and components
import { useState } from "react";
import {
    View,
    Text,
    TouchableOpacity,
} 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;omponent as the default export
export default App;
TaskList.js
// Import the ScrollView component from react-native for scrollable content
import { ScrollView } from "react-native";
// Import the TaskItem component to render individual tasks
import TaskItem from "./TaskItem";
// Import styles from the styles file
import styles from "../styles";

// Define the TaskList functional component with props for tasks and handlers
const TaskList = ({
    tasks, // Array of task objects to display
    handleEditTask, // Function to handle editing a task
    handleToggleCompletion, // Function to toggle task completion status
    handleDeleteTask, // Function to delete a task
}) => {
    // Render the component
    return (
        // Scrollable container for the list of tasks, styled with taskList style
        <ScrollView style={styles.taskList}>
        
            {/* Iterate over each task in the tasks array */}
            {tasks.map((t) => (
                // Render a TaskItem component for each task
                <TaskItem
                    key={t.id} // Unique key for each TaskItem using task's ID
                    task={t} // Pass the entire task object as a prop
                    handleEditTask={handleEditTask} // Pass edit handler function
                    handleToggleCompletion={handleToggleCompletion} // Pass toggle completion handler
                    handleDeleteTask={handleDeleteTask} // Pass delete handler function
                />
            ))}
        </ScrollView>
    );
};
// Export the TaskList component as the default export
export default TaskList;
TaskItem.js
// Import necessary components from react-native
import { View, Text, TouchableOpacity } from "react-native";
// Import styles from the styles file
import styles from "../styles";

// Define the TaskItem functional component with props
const TaskItem = ({
    task, // The task object containing details
    handleEditTask, // Function to handle editing a task
    handleToggleCompletion, // Function to toggle task completion
    handleDeleteTask, // Function to delete a task
}) => {
    return (
        // Container for the entire task item
        <View style={styles.taskItem}>
            {/* Container for task text details */}
            <View style={styles.taskTextContainer}>
                {/* Display the task title, with a different style if completed */}
                <Text
                    style={[
                        styles.taskText,
                        task.status === "Completed" &&
                            styles.completedTaskText,
                    ]}>
                    {task.title}
                </Text>
                {/* Display the task description */}
                <Text style={styles.taskDescription}>
                    {task.description}
                </Text>
                {/* Display the task status */}
                <Text style={styles.taskStatus}>
                    Status: {task.status}
                </Text>
                {/* Display the task deadline */}
                <Text style={styles.taskDeadline}>
                    Deadline: {task.deadline}
                </Text>
                {/* Display the task creation date */}
                <Text style={styles.taskCreatedAt}>
                    Created: {task.createdAt}
                </Text>
            </View>
            {/* Container for action buttons */}
            <View style={styles.buttonContainer}>
                {/* Button to edit the task */}
                <TouchableOpacity
                    onPress={() => handleEditTask(task)}
                    style={[styles.editButton]}>
                    <Text style={styles.buttonText}>
                        Edit
                    </Text>
                </TouchableOpacity>
                {/* Button to toggle completion status */}
                <TouchableOpacity
                    onPress={() =>
                        handleToggleCompletion(task.id)
                    }
                    style={[
                        styles.completeButton,
                        task.status === "Completed" &&
                            styles.completedButton,
                    ]}>
                    <Text style={styles.buttonText}>
                        {task.status === "Completed"
                            ? "Pending"
                            : "Completed"}
                    </Text>
                </TouchableOpacity>
                {/* Button to delete the task */}
                <TouchableOpacity
                    onPress={() =>
                        handleDeleteTask(task.id)
                    }
                    style={[styles.deleteButton]}>
                    <Text style={styles.buttonText}>
                        Delete
                    </Text>
                </TouchableOpacity>
            </View>
        </View>
    );
};

// Export the TaskItem component as default
export default TaskItem;
TaskModal.js
// Import necessary components from react-native
import {
    View,           // Container component for layout
    Text,           // Component for displaying text
    TextInput,      // Input field for text
    Button,         // Button component
    Modal,          // Modal dialog component
} from "react-native";
// Import styles from the styles file
import styles from "../styles";
// Import Calendar component for date picking
import { Calendar } from "react-native-calendars";

// Define the TaskModal functional component with props
const TaskModal = ({
    modalVisible,      // Boolean to control modal visibility
    task,              // Task object containing title, description, deadline, etc.
    setTask,           // Function to update the task state
    handleAddTask,     // Function to handle adding or updating a task
    handleCancel,      // Function to handle cancel action
    validationError,   // Boolean to indicate validation error
}) => {
    return (
        // Modal component to display the task form
        <Modal
            visible={modalVisible}        // Show or hide modal based on modalVisible
            animationType="slide"         // Slide animation for modal appearance
            transparent={false}>          // Modal is not transparent

            {/* Container for modal content */}
            <View style={styles.modalContainer}>
                {/* Input for task title */}
                <TextInput
                    style={styles.input}                  // Style for input
                    placeholder="Title"                   // Placeholder text
                    value={task.title}                    // Value from task object
                    onChangeText={(text) =>               // Update task title on change
                        setTask({ ...task, title: text })
                    }
                />

                {/* Input for task description */}
                <TextInput
                    style={styles.input}                  // Style for input
                    placeholder="Description"             // Placeholder text
                    value={task.description}              // Value from task object
                    onChangeText={(text) =>               // Update task description on change
                        setTask({
                            ...task,
                            description: text,
                        })
                    } />

                {/* Label for deadline */}
                <Text style={styles.inputLabel}>
                    Deadline:
                </Text>
                {/* Calendar component for selecting deadline */}
                <Calendar
                    style={styles.datePicker}             // Style for calendar
                    markedDates={                         // Highlight selected date
                        task.deadline
                            ? { [task.deadline]: { selected: true, selectedColor: '#007BFF' } }
                            : {}
                    }
                    onDayPress={(day) =>                  // Update deadline on date selection
                        setTask({ ...task, deadline: day.dateString })
                    }
                    current={task.deadline}               // Set current date in calendar
                />

                {/* Show validation error if present */}
                {validationError && (
                    <Text style={styles.errorText}>
                        Please fill in all fields correctly.
                    </Text>
                )}
                {/* Button to add or update task */}
                <Button
                    title={task.id ? "Update" : "Add"}    // Show "Update" if editing, else "Add"
                    onPress={handleAddTask}               // Call handleAddTask on press
                    color="#007BFF" />                    // Button color

                {/* Button to cancel and close modal */}
                <Button
                    title="Cancel"                        // Button label
                    onPress={handleCancel}                // Call handleCancel on press
                    color="#FF3B30" />                    // Button color
            </View>
        </Modal>
    );
};

// Export the TaskModal component as default
export default TaskModal;
styles.js
// Import StyleSheet from react-native for creating styles
import { StyleSheet } from "react-native";

// Create a StyleSheet object to hold all styles
const styles = StyleSheet.create({
    // Main container style
    container: {
        flex: 1, // Take up the full screen
        padding: 30, // Padding around the content
        backgroundColor: "#f7f7f7", // Light gray background
    },
    // Title text style
    title: {
        fontSize: 28, // Large font size
        fontWeight: "bold", // Bold text
        marginBottom: 20, // Space below the title
        color: "#333", // Dark text color
        textAlign: "center", // Center the text
    },
    // Task list container style
    taskList: {
        flex: 1, // Take up available space
    },
    // Individual task item style
    taskItem: {
        flexDirection: "row", // Arrange children in a row
        justifyContent: "space-between", // Space between children
        alignItems: "center", // Center items vertically
        backgroundColor: "#fff", // White background
        marginBottom: 10, // Space below each task
        padding: 15, // Padding inside the task item
        borderRadius: 10, // Rounded corners
    },
    // Container for task text
    taskTextContainer: {
        flex: 1, // Take up available space
    },
    // Main task text style
    taskText: {
        fontSize: 18, // Medium font size
        fontWeight: "bold", // Bold text
        color: "#333", // Dark text color
    },
    // Style for completed task text
    completedTaskText: {
        textDecorationLine: "line-through", // Strike-through text
        color: "gray", // Gray color for completed tasks
    },
    // Task description text style
    taskDescription: {
        fontSize: 16, // Slightly smaller font
        color: "#666", // Medium gray color
    },
    // Task time text style
    taskTime: {
        fontSize: 14, // Small font size
        color: "#666", // Medium gray color
    },
    // Task status text style
    taskStatus: {
        fontSize: 16, // Medium font size
        color: "#666", // Medium gray color
    },
    // Container for buttons (edit, complete, delete)
    buttonContainer: {
        flexDirection: "column", // Arrange buttons vertically
        marginVertical: 2, // Vertical margin between buttons
    },
    // Edit button style
    editButton: {
        backgroundColor: "#007BFF", // Blue background
        borderRadius: 5, // Rounded corners
        padding: 10, // Padding inside the button
        marginRight: 10, // Space to the right of the button
        width: 110, // Fixed width
    },
    // Generic button style
    button: {
        marginBottom: 10, // Space below the button
    },
    // Complete button style
    completeButton: {
        backgroundColor: "#4CAF50", // Green background
        borderRadius: 5, // Rounded corners
        padding: 10, // Padding inside the button
        marginRight: 10, // Space to the right of the button
        width: 110, // Fixed width
    },
    // Style for completed (disabled) button
    completedButton: {
        backgroundColor: "#808080", // Gray background
    },
    // Button text style
    buttonText: {
        color: "#fff", // White text
        fontSize: 15, // Medium font size
    },
    // Delete button style
    deleteButton: {
        backgroundColor: "#FF9500", // Orange background
        borderRadius: 5, // Rounded corners
        padding: 10, // Padding inside the button
        width: 110, // Fixed width
    },
    // Add button style (for adding new tasks)
    addButton: {
        alignItems: "center", // Center content horizontally
        justifyContent: "center", // Center content vertically
        backgroundColor: "#007BFF", // Blue background
        paddingVertical: 15, // Vertical padding
        borderRadius: 10, // Rounded corners
        marginTop: 20, // Space above the button
    },
    // Add button text style
    addButtonText: {
        color: "#fff", // White text
        fontSize: 18, // Large font size
        fontWeight: "bold", // Bold text
    },
    // Modal container style
    modalContainer: {
        flex: 1, // Take up the full screen
        padding: 20, // Padding around the content
        backgroundColor: "#fff", // White background
    },
    // Input field style
    input: {
        borderWidth: 1, // Border width
        borderColor: "#ccc", // Light gray border
        padding: 10, // Padding inside the input
        marginBottom: 20, // Space below the input
        borderRadius: 5, // Rounded corners
        fontSize: 16, // Medium font size
    },
    // Input label style
    inputLabel: {
        fontSize: 16, // Medium font size
        fontWeight: "bold", // Bold text
    },
    // Error text style
    errorText: {
        color: "#FF3B30", // Red color for errors
        fontSize: 16, // Medium font size
        marginBottom: 10, // Space below the error text
    },
    // Task deadline text style
    taskDeadline: {
        color: "#FF3B12", // Orange-red color for deadlines
    },
    // Task created-at text style
    taskCreatedAt: {
        color: "#5497FF", // Blue color for creation time
    },
});

// Export the styles object for use in other files
export default styles;

Output



Next Article

Similar Reads