A To-Do List App is a fundamental application used to track tasks that need to be completed. It's an excellent project for beginners to learn core web development concepts, particularly state management, event handling, and rendering dynamic lists. The primary functionalities typically include:
1. Adding New Tasks: Users can input a task description and add it to the list.
2. Displaying Tasks: All added tasks are displayed in a list format.
3. Marking Tasks as Complete/Incomplete: Users can toggle the status of a task, indicating whether it's done or still pending. This often involves visual cues like strikethrough text.
4. Deleting Tasks: Users can remove tasks from the list, usually when they are no longer needed.
In React, building a To-Do List App involves several key concepts:
* State Management (useState hook): The list of to-do items (an array of objects, where each object represents a task with properties like 'id', 'text', and 'completed') is typically stored in the component's state. The `useState` hook is crucial for managing this mutable data.
* Controlled Components: Input fields for adding new tasks are usually 'controlled components', meaning their value is managed by React state, and changes are handled by `onChange` event listeners.
* Event Handling: Functions are used to handle user interactions such as button clicks (e.g., 'Add Task', 'Delete', 'Toggle Complete') and input changes.
* Conditional Rendering: Elements might be rendered conditionally. For example, applying a 'completed' CSS class to a task item if its `completed` status is true.
* List Rendering (map method): The `map()` method is used to iterate over the array of to-do items in the state and render a corresponding component or JSX element for each item. It's essential to provide a unique `key` prop for each item when rendering lists to help React efficiently update the UI.
* Component Structure: A typical structure might involve a main `App` component holding the state and functions, and potentially a separate `TodoItem` component for rendering individual tasks, making the code more modular and reusable.
This application helps solidify understanding of how to build interactive user interfaces where data changes dynamically based on user input and actions.
Example Code
import React, { useState } from 'react';
import './App.css'; // Assuming you have a basic CSS file for styling
function App() {
const [todos, setTodos] = useState([]);
const [inputValue, setInputValue] = useState('');
const addTodo = () => {
if (inputValue.trim() === '') return; // Prevent adding empty todos
const newTodo = {
id: Date.now(), // Unique ID for each todo
text: inputValue,
completed: false,
};
setTodos([...todos, newTodo]);
setInputValue(''); // Clear the input field after adding
};
const toggleTodoComplete = (id) => {
setTodos(todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
));
};
const deleteTodo = (id) => {
setTodos(todos.filter((todo) => todo.id !== id));
};
return (
<div className="todo-app">
<h1>My To-Do List</h1>
<div className="todo-input-container">
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
placeholder="Add a new task..."
/>
<button onClick={addTodo}>Add Task</button>
</div>
<ul className="todo-list">
{todos.map((todo) => (
<li key={todo.id} className={todo.completed ? 'completed' : ''}>
<span onClick={() => toggleTodoComplete(todo.id)}>
{todo.text}
</span>
<button onClick={() => deleteTodo(todo.id)}>Delete</button>
</li>
))}
</ul>
</div>
);
}
export default App;
/*
Basic App.css (create a file named App.css in the same directory):
.todo-app {
font-family: Arial, sans-serif;
max-width: 500px;
margin: 40px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
background-color: #f9f9f9;
}
h1 {
text-align: center;
color: #333;
}
.todo-input-container {
display: flex;
margin-bottom: 20px;
}
.todo-input-container input {
flex-grow: 1;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px 0 0 4px;
font-size: 16px;
}
.todo-input-container button {
padding: 10px 15px;
background-color: #007bff;
color: white;
border: none;
border-radius: 0 4px 4px 0;
cursor: pointer;
font-size: 16px;
}
.todo-input-container button:hover {
background-color: #0056b3;
}
.todo-list {
list-style: none;
padding: 0;
}
.todo-list li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #eee;
background-color: #fff;
margin-bottom: 5px;
border-radius: 4px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.todo-list li:last-child {
border-bottom: none;
}
.todo-list li span {
flex-grow: 1;
cursor: pointer;
font-size: 16px;
color: #333;
}
.todo-list li.completed span {
text-decoration: line-through;
color: #888;
}
.todo-list li button {
background-color: #dc3545;
color: white;
border: none;
padding: 6px 10px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
margin-left: 10px;
}
.todo-list li button:hover {
background-color: #c82333;
}
*/








To-Do List App