DEV Community

Vishal Yadav
Vishal Yadav

Posted on

Building a TODO List App in React.js with Local Storage.

Image description
React.js is a popular JavaScript library for building user interfaces, and it’s a great choice for creating web applications like a TODO list. In this blog, we will walk you through the process of building a TODO list app using React.js, with the added functionality of local storage to persist your tasks even after you close the browser.

Prerequisites
Before we get started, make sure you have the following prerequisites:

Node.js and npm installed on your computer.
Building a TODO List App in React.js with Local Storage
React.js is a popular JavaScript library for building user interfaces, and it’s a great choice for creating web applications like a TODO list. In this blog, we will walk you through the process of building a TODO list app using React.js, with the added functionality of local storage to persist your tasks even after you close the browser.Prerequisites

Before we get started, make sure you have the following prerequisites:

Node.js installed on your computer.

Step 1: Create a New React App
We will start by creating a new React app using Vite which is a popular tool for setting up a new React project with a predefined folder structure.

Open your terminal and run the following commands:

npm create vite@latest todo-app
cd todo-app
npm i
Enter fullscreen mode Exit fullscreen mode

This will create a new directory named todo-app and set up a basic React project structure inside it.

Step 2: Building the TODO List
Now, let’s dive into the development of our TODO list app. We’ll create a simple interface with an input field to add tasks and a list to display them.

2.1. Todo.jsx
Open the src/components/Todo.jsx file and replace its contents with the following code:

import { useEffect, useState } from "react";
import "./Todo.css"; 
import TodoItem from "./TodoItem";
Enter fullscreen mode Exit fullscreen mode
const Todo = () => {
  const [task, setTask] = useState([]);
  const [todo, setTodo] = useState("");

  useEffect(() => {
    const stored = JSON.parse(localStorage.getItem("todo"));
    if (stored) {
      setTask(stored);
    }
  }, []);

  const updateLocalStorage = (updatedTasks) => {
    localStorage.setItem("todo", JSON.stringify(updatedTasks));
    setTask(updatedTasks);
  };

  const addTodo = () => {
    if (todo.trim() !== "") {
      const newTask = { id: Date.now(), task: todo, completed: false };
      const updatedTasks = [...task, newTask];
      updateLocalStorage(updatedTasks);
      setTodo("");
    }
  };

  const deleteTodo = (id) => {
    const updatedTasks = task.filter((item) => item.id !== id);
    updateLocalStorage(updatedTasks);
  };

  const toggleTodo = (id) => {
    const updatedTasks = task.map((item) =>
      item.id === id ? { ...item, completed: !item.completed } : item
    );
    updateLocalStorage(updatedTasks);
  };

  return (
    <div className="todo-container">
      <h1>Todo</h1>
      <div className="add-todo">
        <input
          type="text"
          className="input-todo"
          value={todo}
          onChange={(e) => setTodo(e.target.value)}
        />
        <button className="todo-btn" onClick={addTodo}>
          Add Todo
        </button>
      </div>
      <div className="todo-list">
        <h1>Todo List</h1>
        <ul>
          {task.map((item) => (
            <TodoItem
              key={item.id}
              item={item}
              onDelete={deleteTodo}
              onToggle={toggleTodo}
            />
          ))}
        </ul>
      </div>
    </div>
  );
};

export default Todo;
Enter fullscreen mode Exit fullscreen mode

This code sets up the main structure of your TODO app. We’re using React hooks to manage the state of the TODOs and to interact with local storage.

2.1.2 Todo.css
To make the app look good, we need some basic styling. Create a file named Todo.css in the src directory and add the following CSS:

.todo-container {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
  background-color: #f9f9f9;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.add-todo {
  margin-bottom: 20px;
}

.input-todo {
  padding: 10px;
  width: 70%;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.todo-btn {
  padding: 10px 20px;
  border: none;
  background-color: #007bff;
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.todo-btn:hover {
  background-color: #0056b3;
}

.todo-list {
  list-style-type: none;
  padding: 0;
}

.todo-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.todo-item p {
  margin: 0;
  flex-grow: 1;
  padding-left: 10px;
}

.completed {
  text-decoration: line-through;
  color: #888;
}

.delete-btn {
  margin-left: 10px;
  background-color: #dc3545;
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 5px 10px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.delete-btn:hover {
  background-color: #c82333;
}
Enter fullscreen mode Exit fullscreen mode

2.2. TodoItem.jsx
Open the src/components/TodoItem.jsx file and replace its contents with the following code:

mport PropTypes from "prop-types";
import "./TodoItem.css";
const TodoItem = ({ item, onDelete, onToggle }) => {
  return (
    <li className="todo-item">
      {" "}
      <input
        type="checkbox"
        checked={item.completed}
        onChange={() => onToggle(item.id)}
      />
      <p className={item.completed ? "completed" : ""}>{item.task}</p>
      <button className="todo-btn" onClick={() => onDelete(item.id)}>
        Delete Todo
      </button>
    </li>
  );
};

TodoItem.propTypes = {
  item: PropTypes.shape({
    id: PropTypes.number.isRequired,
    task: PropTypes.string.isRequired,
    completed: PropTypes.bool.isRequired,
  }).isRequired,
  onDelete: PropTypes.func.isRequired,
  onToggle: PropTypes.func.isRequired,
};

export default TodoItem;
Enter fullscreen mode Exit fullscreen mode

2.2.1 TodoItem.css
To make the app look good, we need some basic styling. Create a file named TodoItem.css in the src directory and add the following CSS:

.todo-item {
  display: flex;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid #ccc;
}

.todo-item p {
  margin: 0;
  padding-left: 10px;
  flex-grow: 1;
}

.completed {
  text-decoration: line-through;
  color: #888;
}

.todo-btn {
  padding: 5px 10px;
  background-color: #dc3545;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.todo-btn:hover {
  background-color: #c82333;
}
Enter fullscreen mode Exit fullscreen mode

2.3. App.Jsx
Import the your todo component here to get the final result , here how you can do that:

import "./App.css";
import Todo from "./components/Todo";
function App() {
  return (
    <>
      <Todo />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

2.3.1 App.css
Import the some css here to align div at center for your root, here how you can do that:

#root {
  max-width: 1280px;
  margin: 0 auto;
  padding: 2rem;
  text-align: center;
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Running the App
Now that you’ve created your TODO app, you can run it by executing the following command in the terminal:

npm run dev
Enter fullscreen mode Exit fullscreen mode

This will start your React app, and you can access it in your web browser at http://localhost:5173.

Step 4: Using the TODO App
Your TODO app allows you to add tasks by typing in the input field and clicking the “Add Todo” button. Once you’ve added a task, it will appear in the list below. To remove a task, simply click the “Delete Todo” button next to it. What makes this app special is that it also uses local storage to persist your tasks. Even if you close the browser and reopen it, your tasks will still be there.

Conclusion
Congratulations! You’ve successfully built a TODO list app in React.js with local storage. This app provides a user-friendly interface for managing your tasks and ensures that your tasks are saved and loaded from local storage, making it a practical and efficient tool for your daily productivity needs.

Top comments (0)