React Todo List: Creating and Sharing Reusable Components with Best Practices

React Todo List: Creating and Sharing Reusable Components with Best Practices

In this guide, we will build a Todo App using React while focusing on reusability, component structuring, and best practices to optimize your application.

Key Features

- Modular and reusable components.
- Add, edit, and delete tasks.
- Mark tasks as completed.
- Filter tasks (All, Completed, Pending).
- Store tasks in local storage for persistence.
- Display a real-time digital clock showing the current date and time.
- Clear all tasks with a single button.

Installation and Setup

    
// Create a new React project
npx create-react-app todo-app
cd todo-app
npm start
    
  

Reusable Todo List Component

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

function TodoList({ tasks, toggleTask }) {
  return (
    
    {tasks.map((task, index) => (
  • toggleTask(index)} className={`p-2 border rounded-md cursor-pointer ${task.completed ? 'line-through text-gray-500' : ''}`} > {task.text}
  • ))}
); } export default TodoList;

Todo App Component with Reusable Components

    
import React, { useState, useEffect } from "react";
import TodoList from "./TodoList";

function TodoApp() {
  const [tasks, setTasks] = useState([]);
  const [newTask, setNewTask] = useState("");
  const [currentTime, setCurrentTime] = useState(new Date());

  useEffect(() => {
    const storedTasks = JSON.parse(localStorage.getItem("tasks")) || [];
    setTasks(storedTasks);
  }, []);

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

  useEffect(() => {
    const timer = setInterval(() => {
      setCurrentTime(new Date());
    }, 1000);
    return () => clearInterval(timer);
  }, []);

  const addTask = () => {
    if (newTask.trim() === "") return;
    setTasks([...tasks, { text: newTask, completed: false }]);
    setNewTask("");
  };

  const toggleTask = (index) => {
    const updatedTasks = tasks.map((task, i) =>
      i === index ? { ...task, completed: !task.completed } : task
    );
    setTasks(updatedTasks);
  };

  const clearTasks = () => {
    setTasks([]);
    localStorage.removeItem("tasks");
  };

  return (
    

Todo List

Current Time: {currentTime.toLocaleTimeString()}

setNewTask(e.target.value)} className="border p-2 w-full mb-2" />
); } export default TodoApp;

Best Practices for Reusability

- Keep components small and focused on a single responsibility.
- Use props to pass data and functions between components.
- Separate UI and logic into different components.
- Store reusable components in a separate folder for better organization.