React To-Do List Tutorial
Learn how to create a functional To-Do list application using React's core concepts like components, state management, and event handling.
1. Set Up Your React App
First, create a new React application using create-react-app
or your preferred build tool. We'll use functional components with React hooks.
npx create-react-app todo-tutorial
cd todo-tutorial
npm start
2. Component Structure
This To-Do list will have three components:
- App: Main container component to manage state
- TodoForm: Input form to add new tasks
- TodoList: Renders list items
3. Implement the To-Do Form
Use the useState hook to manage the input state and form submission.
// TodoForm.js
import { useState } from 'react';
function TodoForm({ addTodo }) {
const [text, setText] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
if (text.trim() !== '') {
addTodo(text);
setText('');
}
};
return (
<form className="flex gap-2" onSubmit={handleSubmit}>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Add new task"
className="flex-1 px-4 py-2 rounded-l-lg border border-gray-300"
/>
<button
type="submit"
className="bg-cyan-600 text-white px-4 py-2 rounded-r-lg hover:bg-cyan-700 transition-colors"
>
Add
</button>
</form>
);
}
4. Display and Manage To-Do Items
Here's the complete To-Do list implementation with state management:
// App.js
import { useState } from 'react';
import TodoForm from './TodoForm';
import TodoList from './TodoList';
function App() {
const [todos, setTodos] = useState([
{ id: 1, text: 'Complete tutorial', completed: false },
{ id: 2, text: 'Write JavaScript', completed: true },
{ id: 3, text: 'Create React app', completed: false },
]);
const addTodo = (text) => {
setTodos([
...todos,
{ id: Date.now(), text, completed: false }
]);
};
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));
};
return (
<div className="max-w-md mx-auto">
<h1 className="text-2xl font-bold mb-4 text-cyan-600">My To-Do List</h1>
<TodoForm addTodo={addTodo} />
<TodoList todos={todos} toggleTodo={toggleTodo} deleteTodo={deleteTodo} />
</div>
);
}
export default App;
5. Create To-Do Item Component
// TodoList.js
export default function TodoList({ todos, toggleTodo, deleteTodo }) {
return (
<ul className="space-y-3 mt-4">
{todos.map((todo) => (
<li key={todo.id} className="bg-gray-50 p-3 rounded-lg flex justify-between items-center">
<div className="flex items-center">
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
className="mr-2"
/>
<span className={todo.completed ? 'line-through text-gray-500' : ''}>
{todo.text}
</span>
</div>
<button
onClick={() => deleteTodo(todo.id)}
className="text-red-500 hover:text-red-700 transition-colors"
>
×
</button>
</li>
))}
</ul>
);
}
6. Try the Example
Click the button below to see a working To-Do list example with complete state handling and interactivity:
View ExampleInteractive To-Do Example
7. Key Concepts Demonstrated
- useState – For managing input and todo state
- Event Handling – Handling form submissions and checkbox changes
- Conditional Rendering – Strikethrough completed items
- Component Separation – Form and List as separate components
- JSX – Declarative UI updates