How to Build a To-Do List App with React.js
![]() |
In this article, we’ll walk you through the process of creating a fully functional to-do list app using React.js. By the end, you’ll have a solid understanding of React fundamentals, including components, state management, and event handling. Let’s dive in!
Why Build a To-Do List App with React.js?
React.js is a powerful library for building user interfaces. It’s component-based, which means you can break down your app into smaller, reusable pieces. This makes React ideal for creating dynamic and interactive applications like a to-do list.
Here’s why building a to-do list app is a great project:
- Beginner-friendly: It’s simple enough for beginners but offers room for advanced features.
- Practical: You’ll create something you can actually use in your daily life.
- Skill-building: You’ll learn core React concepts like state management, props, and event handling.
Prerequisites
Before we start, make sure you have the following:
- Node.js installed on your machine.
- A basic understanding of HTML, CSS, and JavaScript.
- Familiarity with React.js basics (components, JSX, and state).
If you’re new to React, don’t worry! This guide is designed to be beginner-friendly.
Step 1: Set Up Your React Project
First, let’s create a new React project using Create React App, a tool that sets up a React environment for you.
- Open your terminal and run:
npx create-react-app todo-list-app
- Navigate to the project folder:
cd todo-list-app
- Start the development server:
npm start
Your React app should now be running on http://localhost:3000
.
Step 2: Create the Basic Structure
Let’s start by creating the basic structure of our to-do list app. We’ll need:
- An input field to add new tasks.
- A button to submit the task.
- A list to display all tasks.
Open the src/App.js
file and replace its content with the following code:
import React, { useState } from 'react';
import './App.css';
function App() {
const [tasks, setTasks] = useState([]);
const [inputValue, setInputValue] = useState('');
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
const handleAddTask = () => {
if (inputValue.trim() !== '') {
setTasks([...tasks, inputValue]);
setInputValue('');
}
};
return (
<div className="App">
<h1>My To-Do List</h1>
<div className="todo-container">
<input
type="text"
value={inputValue}
onChange={handleInputChange}
placeholder="Add a new task"
/>
<button onClick={handleAddTask}>Add Task</button>
</div>
<ul>
{tasks.map((task, index) => (
<li key={index}>{task}</li>
))}
</ul>
</div>
);
}
export default App;
Step 3: Style Your App
Let’s make our app look clean and user-friendly. Open the src/App.css
file and add the following styles:
.App {
text-align: center;
font-family: Arial, sans-serif;
max-width: 400px;
margin: 0 auto;
padding: 20px;
}
h1 {
color: #333;
}
.todo-container {
margin-bottom: 20px;
}
input {
padding: 10px;
width: 70%;
margin-right: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 10px 15px;
background-color: #28a745;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #218838;
}
ul {
list-style-type: none;
padding: 0;
}
li {
background-color: #f8f9fa;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 4px;
display: flex;
justify-content: space-between;
align-items: center;
}
Step 4: Add Task Completion and Deletion Features
A to-do list isn’t complete without the ability to mark tasks as done or delete them. Let’s enhance our app with these features.
Update the App.js
file as follows:
import React, { useState } from 'react';
import './App.css';
function App() {
const [tasks, setTasks] = useState([]);
const [inputValue, setInputValue] = useState('');
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
const handleAddTask = () => {
if (inputValue.trim() !== '') {
setTasks([...tasks, { text: inputValue, completed: false }]);
setInputValue('');
}
};
const handleCompleteTask = (index) => {
const updatedTasks = tasks.map((task, i) =>
i === index ? { ...task, completed: !task.completed } : task
);
setTasks(updatedTasks);
};
const handleDeleteTask = (index) => {
const updatedTasks = tasks.filter((_, i) => i !== index);
setTasks(updatedTasks);
};
return (
<div className="App">
<h1>My To-Do List</h1>
<div className="todo-container">
<input
type="text"
value={inputValue}
onChange={handleInputChange}
placeholder="Add a new task"
/>
<button onClick={handleAddTask}>Add Task</button>
</div>
<ul>
{tasks.map((task, index) => (
<li key={index} className={task.completed ? 'completed' : ''}>
<span>{task.text}</span>
<div>
<button onClick={() => handleCompleteTask(index)}>
{task.completed ? 'Undo' : 'Complete'}
</button>
<button onClick={() => handleDeleteTask(index)}>Delete</button>
</div>
</li>
))}
</ul>
</div>
);
}
export default App;
Step 5: Save Tasks to Local Storage (Optional)
To make your app more practical, you can save tasks to the browser’s local storage so they persist even after refreshing the page.
Add the following code to App.js
:
import React, { useState, useEffect } from 'react';
import './App.css';
function App() {
const [tasks, setTasks] = useState([]);
const [inputValue, setInputValue] = useState('');
// Load tasks from local storage on initial render
useEffect(() => {
const savedTasks = JSON.parse(localStorage.getItem('tasks')) || [];
setTasks(savedTasks);
}, []);
// Save tasks to local storage whenever tasks change
useEffect(() => {
localStorage.setItem('tasks', JSON.stringify(tasks));
}, [tasks]);
// ... rest of the code remains the same
}
export default App;
Conclusion
Congratulations! You’ve built a fully functional to-do list app using React.js. Along the way, you’ve learned how to:
- Manage state with
useState
. - Handle user input and events.
- Style your app with CSS.
- Add advanced features like task completion and deletion.
- Save data to local storage.
This project is just the beginning. You can expand it by adding features like due dates, task categories, or even integrating it with a backend. Keep experimenting and building, and you’ll soon master React.js!
Happy coding! 🚀