Creating a ToDo List application is an excellent way to get started with ReactJS. This tutorial provides a step-by-step guide to building a functional and stylish ToDo app. By following these seven steps, you’ll learn essential React concepts such as components, state management, event handling, and local storage integration. Whether you’re new to React or looking to sharpen your skills, this tutorial offers a practical and rewarding learning experience. By the end, you’ll have a fully operational ToDo List application and a deeper understanding of how React works under the hood.

Setting Up Your React Project

Installing Node.js and npm

Download and Install Node.js: Head over to the official Node.js website to download the installer. Opt for the LTS (Long Term Support) version for better reliability and ongoing updates.
Install npm: Alongside Node.js, the installation automatically includes npm (Node Package Manager), an essential tool for handling JavaScript libraries and dependencies.

Creating a New React Application

Install Create React App: Open your terminal and use the command npm install -g create-react-app to globally install this utility for scaffolding React projects.
Generate Your Application: Run the command npx create-react-app my-app to set up a new directory named my-app, preconfigured with everything you need to start coding.

Understanding the Application Structure

Review the Setup: Enter your project folder and examine the default structure created by Create React App. The key directories include public, which stores static assets, src, which holds the app’s source code, and node_modules, where the app’s dependencies are located.
Important Files: Inside the src folder, you’ll find App.js, the main component of your application, and index.js, which mounts the root component to the DOM.

Running the Development Server

Start the Server: Within your project folder, use the npm start command to initiate the development server. This will build the application and open it in your default web browser.
Live Updates: Any edits made to your source files will instantly update in the browser, courtesy of React’s hot reloading feature.

This streamlined setup process, powered by Create React App, removes the hassle of manual configuration and gives you a ready-to-use project structure, so you can dive straight into building your React application.


Prerequisites

Before diving in, ensure you have the following:

  • Basic knowledge of JavaScript and HTML.
  • Node.js and npm installed on your computer.
  • A code editor (like Visual Studio Code).

Step 1: Set Up Your React Environment

Begin by setting up your development environment. First, open your terminal and run the following command to install Create React App:

npx create-react-app todo-app

This will create a React application with all necessary dependencies and configurations. Navigate to the project directory with:

cd todo-app

Start the development server by running:

npm start

Your browser should open automatically, displaying the default React app at http://localhost:3000. You’re now ready to begin building your ToDo List application.


Step 2: Create the ToDo Component Structure

React applications are modular, built using reusable components. For managing tasks, create a dedicated ToDo component. Inside the src folder, create a new file named ToDo.js. Add the following code:

import React from 'react';

const ToDo = () => {
    return (
        <div className="todo-container">
            <h1>ToDo List</h1>
        </div>
    );
};

export default ToDo;

Update App.js to include this component:

import React from 'react';
import ToDo from './ToDo';

const App = () => {
    return (
        <div>
            <ToDo />
        </div>
    );
};

export default App;

This step establishes a basic structure for your app, providing a dedicated area to manage tasks.


Step 3: Add State to Manage Tasks

React’s useState hook allows dynamic state management within components. Update the ToDo component to include state variables for managing tasks and user input. Modify your code as follows:

import React, { useState } from 'react';

const ToDo = () => {
    const [tasks, setTasks] = useState([]);
    const [task, setTask] = useState("");

    const addTask = () => {
        if (task) {
            setTasks([...tasks, task]);
            setTask("");
        }
    };

    return (
        <div className="todo-container">
            <h1>ToDo List</h1>
            <input
                type="text"
                placeholder="Enter a task"
                value={task}
                onChange={(e) => setTask(e.target.value)}
            />
            <button onClick={addTask}>Add Task</button>
            <ul>
                {tasks.map((t, index) => (
                    <li key={index}>{t}</li>
                ))}
            </ul>
        </div>
    );
};

export default ToDo;

This code enables users to add tasks dynamically to the list.


Step 4: Add Styling

Enhance the app’s appearance with custom styling. Create a new file ToDo.css in the src folder and add the following styles:

.todo-container {
    max-width: 500px;
    margin: 50px auto;
    text-align: center;
}

input {
    width: 70%;
    padding: 10px;
    margin-right: 10px;
}

button {
    padding: 10px 20px;
    background-color: #28a745;
    color: white;
    border: none;
    cursor: pointer;
}

ul {
    list-style-type: none;
    padding: 0;
}

li {
    background: #f8f9fa;
    margin: 5px 0;
    padding: 10px;
    border: 1px solid #dee2e6;
}

Import the CSS file in ToDo.js:

import './ToDo.css';

This step makes your application visually appealing and user-friendly.


Step 5: Add Delete Functionality

Allow users to remove tasks by implementing a delete feature. Update the ToDo component as follows:

 

const ToDo = () => {
    const [tasks, setTasks] = useState([]);
    const [task, setTask] = useState("");

    const addTask = () => {
        if (task) {
            setTasks([...tasks, task]);
            setTask("");
        }
    };

    const deleteTask = (index) => {
        setTasks(tasks.filter((_, i) => i !== index));
    };

    return (
        <div className="todo-container">
            <h1>ToDo List</h1>
            <input
                type="text"
                placeholder="Enter a task"
                value={task}
                onChange={(e) => setTask(e.target.value)}
            />
            <button onClick={addTask}>Add Task</button>
            <ul>
                {tasks.map((t, index) => (
                    <li key={index}>
                        {t} <button onClick={() => deleteTask(index)}>Delete</button>
                    </li>
                ))}
            </ul>
        </div>
    );
};

This functionality enables users to efficiently manage their task list.


Step 6: Save Tasks to Local Storage

Ensure tasks persist across page reloads by integrating local storage. Update the ToDo component with saving and loading logic:

import React, { useState, useEffect } from 'react';

const ToDo = () => {
    const [tasks, setTasks] = useState(() => {
        const savedTasks = localStorage.getItem("tasks");
        return savedTasks ? JSON.parse(savedTasks) : [];
    });
    const [task, setTask] = useState("");

    useEffect(() => {
        localStorage.setItem("tasks", JSON.stringify(tasks));
    }, [tasks]);

    const addTask = () => {
        if (task) {
            setTasks([...tasks, task]);
            setTask("");
        }
    };

    const deleteTask = (index) => {
        setTasks(tasks.filter((_, i) => i !== index));
    };

    return (
        <div className="todo-container">
            <h1>ToDo List</h1>
            <input
                type="text"
                placeholder="Enter a task"
                value={task}
                onChange={(e) => setTask(e.target.value)}
            />
            <button onClick={addTask}>Add Task</button>
            <ul>
                {tasks.map((t, index) => (
                    <li key={index}>
                        {t} <button onClick={() => deleteTask(index)}>Delete</button>
                    </li>
                ))}
            </ul>
        </div>
    );
};

export default ToDo;

This ensures tasks are saved and reloaded automatically.


Step 7: Enhance with Editable Tasks

Allow users to edit tasks for better flexibility. Update the ToDo component as follows:

const ToDo = () => {
    const [tasks, setTasks] = useState(() => {
        const savedTasks = localStorage.getItem("tasks");
        return savedTasks ? JSON.parse(savedTasks) : [];
    });
    const [task, setTask] = useState("");
    const [editingIndex, setEditingIndex] = useState(null);

    useEffect(() => {
        localStorage.setItem("tasks", JSON.stringify(tasks));
    }, [tasks]);

    const addTask = () => {
        if (task) {
            if (editingIndex !== null) {
                const updatedTasks = [...tasks];
                updatedTasks[editingIndex] = task;
                setTasks(updatedTasks);
                setEditingIndex(null);
            } else {
                setTasks([...tasks, task]);
            }
            setTask("");
        }
    };

    const editTask = (index) => {
        setTask(tasks[index]);
        setEditingIndex(index);
    };

    const deleteTask = (index) => {
        setTasks(tasks.filter((_, i) => i !== index));
    };

    return (
        <div className="todo-container">
            <h1>ToDo List</h1>
            <input
                type="text"
                placeholder="Enter a task"
                value={task}
                onChange={(e) => setTask(e.target.value)}
            />
            <button onClick={addTask}>{editingIndex !== null ? "Update Task" : "Add Task"}</button>
            <ul>
                {tasks.map((t, index) => (
                    <li key={index}>
                        {t} <button onClick={() => editTask(index)}>Edit</button> <button onClick={() => deleteTask(index)}>Delete</button>
                    </li>
                ))}
            </ul>
        </div>
    );
};

export default ToDo;

This enhancement adds flexibility and a polished user experience.


Conclusion

Congratulations! You’ve successfully built a fully functional ToDo List application using ReactJS. This project has introduced you to several key concepts, such as creating reusable components, managing state with the useState hook, handling user events, and persisting data with local storage. Additionally, you learned how to enhance user experience by adding features like task editing and deletion, making your application both dynamic and interactive. If you want to dive deeper into React development or need further guidance, feel free to join Kaashiv Infotech for more hands-on learning and expert mentorship.

This ToDo List app is a solid foundation for exploring more advanced features of React. You can expand on it by adding functionalities like drag-and-drop task reordering, task prioritization, or integration with a backend API for syncing data across devices. By completing this tutorial, you’ve gained hands-on experience and a deeper understanding of how React works, giving you the confidence to take on more complex projects.

Keep experimenting and building—React’s potential is vast, and the skills you’ve learned here will serve as the building blocks for creating amazing web applications. Happy coding!