To-do List

Technology: React.js

Problem Statement

Using ReactJS, create a Todo List with following components/features:

  1. An input field to add new items to the list.
  2. Clicking the task item should mark it as completed (use strike-through).
  3. A button to delete the particular task item from the list.
  4. A counter that updates based on the number of items in the list.
  5. Should have the following set of tasks as the initial items in the list
    • Work on React assessment
    • Water the plants

Solution

State Variables:

  • [array] tasks – To store all todo list items.
  • [string] newTask – To store the value of new task.

Primary Components:

  • Input Form – To provide user the ability to enter a new task.
  • List – To display all the tasks present in the todo list.
  • Text (any) – To display total number of tasks currently present in the todo list.

Functions:

  • addTask
  • toggleDone
  • deleteTask

We have been given an initial list of items which are supposed to be already present in the todo list. We will initialise the tasks state with this given list. Adding necessary event listeners and functions, we will get the following final code.

import "./styles.css";
import { useState } from "react";

export default function App() {
  const initialState = [
    { id: 1, item: "Work on react assessment", done: false },
    { id: 2, item: "Water the plants", done: false }
  ];

  const [tasks, setTasks] = useState(initialState);
  const [newTask, setNewTask] = useState("");

  const addTask = (e) => {
    e.preventDefault();

    if (newTask.trim().length === 0) {
      alert("Input field cannot be empty!");
      return;
    }

    const newId = tasks.length + 1;
    const newTaskObj = { id: newId, item: newTask, done: false };

    setTasks((prevTasks) => [...prevTasks, newTaskObj]);
    setNewTask("");
  };

  const toggleDone = (taskId) => {
    setTasks((prevTasks) =>
      prevTasks.map((task) =>
        task.id === taskId ? { ...task, done: !task.done } : task
      )
    );
  };

  const deleteTask = (taskId) => {
    setTasks((prevTasks) => prevTasks.filter((task) => task.id !== taskId));
  };

  return (
    <div className="App">
      <form onSubmit={addTask}>
        <input
          value={newTask}
          onChange={(e) => setNewTask(e.target.value)}
          id="newTask"
          type="text"
          placeholder="Add a new task"
        />
        <button type="submit">Submit</button>
      </form>
      <div className="tasks">
        <h2>
          Tasks <sup>{tasks.length}</sup>
        </h2>
        <ul>
          {tasks.map((task) => (
            <li
              key={task.id}
              className={task.done ? "finished" : ""}
              onClick={() => toggleDone(task.id)}
            >
              <span>{task.item}</span>
              <button onClick={() => deleteTask(task.id)}>Delete</button>
              <div style={{clear: "both"}}></div>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

For visual step-by-step explanation, you can check out the following video: VIDEO_LINK.