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.