Todo App Project
Every React beginner builds a Todo app – and for good reason. It's the perfect project to understand the core concepts of React: components, state, props, events, and forms. In this chapter, we'll build a complete Todo application step by step.
What We're Building
A classic Todo app where users can:
- Add new todos.
- Mark todos as completed.
- Delete todos.
- Filter todos (All / Active / Completed).
A Todo app is like the "Hello World" of React – it touches every fundamental concept and gives you a solid foundation.
Step 1: Setting Up the Project
npx create-react-app todo-appcd todo-appnpm startStep 2: Planning Components
We'll create these components:
App– main container, holds state and logic.TodoForm– input field to add new todos.TodoList– renders the list of todos.TodoItem– individual todo with checkbox and delete button.FilterButtons– buttons to change filter.
Step 3: Building the App Component
import React, { useState } from 'react';import TodoForm from './TodoForm';import TodoList from './TodoList';import FilterButtons from './FilterButtons';
function App() { const [todos, setTodos] = useState([]); const [filter, setFilter] = useState('all');
const addTodo = (text) => { const newTodo = { id: Date.now(), text, completed: false }; setTodos([...todos, newTodo]); };
const toggleTodo = (id) => { setTodos(todos.map(todo => todo.id === id ? { ...todo, completed: !todo.completed } : todo )); };
const deleteTodo = (id) => { setTodos(todos.filter(todo => todo.id !== id)); };
const getFilteredTodos = () => { switch (filter) { case 'active': return todos.filter(todo => !todo.completed); case 'completed': return todos.filter(todo => todo.completed); default: return todos; } };
return ( <div> <h1>Todo App</h1> <TodoForm addTodo={addTodo} /> <FilterButtons filter={filter} setFilter={setFilter} /> <TodoList todos={getFilteredTodos()} toggleTodo={toggleTodo} deleteTodo={deleteTodo} /> </div> );}
export default App;Step 4: TodoForm Component
import React, { useState } from 'react';
function TodoForm({ addTodo }) { const [text, setText] = useState('');
const handleSubmit = (e) => { e.preventDefault(); if (text.trim()) { addTodo(text); setText(''); } };
return ( <form onSubmit={handleSubmit}> <input type="text" value={text} onChange={(e) => setText(e.target.value)} placeholder="Add a new todo..." /> <button type="submit">Add</button> </form> );}
export default TodoForm;Step 5: TodoItem and TodoList Components
<!-- TodoItem.js -->function TodoItem({ todo, toggleTodo, deleteTodo }) { return ( <li> <input type="checkbox" checked={todo.completed} onChange={() => toggleTodo(todo.id)} /> <span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}> {todo.text} </span> <button onClick={() => deleteTodo(todo.id)}>Delete</button> </li> );}
<!-- TodoList.js -->function TodoList({ todos, toggleTodo, deleteTodo }) { return ( <ul> {todos.map(todo => ( <TodoItem key={todo.id} todo={todo} toggleTodo={toggleTodo} deleteTodo={deleteTodo} /> ))} </ul> );}Step 6: FilterButtons Component
function FilterButtons({ filter, setFilter }) { const filters = ['all', 'active', 'completed']; return ( <div> {filters.map(f => ( <button key={f} onClick={() => setFilter(f)} style={{ fontWeight: filter === f ? 'bold' : 'normal' }} > {f.charAt(0).toUpperCase() + f.slice(1)} </button> ))} </div> );}Two Minute Drill
- A Todo app teaches React fundamentals: components, state, props, events, and forms.
- Use `useState` to manage todos and filter.
- Break UI into small, reusable components.
- Pass data down via props, and pass functions up to modify state.
- Filtering is done by computing a derived list based on filter state.
Need more clarification?
Drop us an email at career@quipoinfotech.com
