
Building a simple to-do list is one of the best ways to learn the fundamentals of React. It teaches you how to manage state, handle user input, render dynamic content, and structure components effectively.
In this tutorial, you’ll learn how to create a basic to-do app using React functional components and hooks like useState
.
Why Build a To-Do App in React?
A to-do list is a beginner-friendly project that introduces core React concepts such as:
- Component-based architecture
- State management
- Event handling
- List rendering with dynamic updates
- Controlled components (forms and inputs)
It’s simple enough to finish quickly, yet powerful enough to demonstrate practical usage of React features.
Project Setup
Before we begin, ensure you have the following installed:
- Node.js and npm (for running the React development server)
- Code editor like Visual Studio Code
Step 1: Create a React App
You can generate a new React project using the following command:
npx create-react-app react-todo-app
cd react-todo-app
npm start
This sets up the project with all the necessary configurations and starts the development server.
Step 2: Structure the App
For simplicity, we’ll build everything inside the App.js
file. Later, you can split it into multiple components for better modularity.
Step 3: Set Up State with useState
In App.js
, start by importing useState
:
import React, { useState } from 'react';
Now define state for the input field and the to-do list:
function App() {
const [task, setTask] = useState('');
const [todos, setTodos] = useState([]);
return (
<div>
<h1>React To-Do App</h1>
</div>
);
}
export default App;
Step 4: Create the Input Form
Add an input field and a button to let users enter new tasks:
<form onSubmit={(e) => {
e.preventDefault();
if (task.trim() === '') return;
setTodos([...todos, task]);
setTask('');
}}>
<input
type="text"
value={task}
onChange={(e) => setTask(e.target.value)}
placeholder="Enter a task"
/>
<button type="submit">Add Task</button>
</form>
This creates a controlled component, where the value of the input is tied to the component’s state.
Step 5: Display the To-Do List
Render the list using map()
:
<ul>
{todos.map((todo, index) => (
<li key={index}>{todo}</li>
))}
</ul>
Now your app shows every task added via the input field.
Step 6: Add Delete Functionality
Let’s enable users to remove tasks from the list:
<ul>
{todos.map((todo, index) => (
<li key={index}>
{todo}
<button onClick={() => {
const newTodos = todos.filter((_, i) => i !== index);
setTodos(newTodos);
}}>
Delete
</button>
</li>
))}
</ul>
This uses filter()
to create a new array excluding the task at the selected index.
Full App Code (App.js)
import React, { useState } from 'react';
function App() {
const [task, setTask] = useState('');
const [todos, setTodos] = useState([]);
const handleSubmit = (e) => {
e.preventDefault();
if (task.trim() === '') return;
setTodos([...todos, task]);
setTask('');
};
const handleDelete = (index) => {
const newTodos = todos.filter((_, i) => i !== index);
setTodos(newTodos);
};
return (
<div style={{ maxWidth: '400px', margin: 'auto', padding: '1rem' }}>
<h1>React To-Do App</h1>
<form onSubmit={handleSubmit}>
<input
type="text"
value={task}
onChange={(e) => setTask(e.target.value)}
placeholder="Enter a task"
style={{ width: '70%', padding: '8px' }}
/>
<button type="submit" style={{ padding: '8px 12px', marginLeft: '8px' }}>
Add
</button>
</form>
<ul style={{ listStyle: 'none', padding: 0 }}>
{todos.map((todo, index) => (
<li key={index} style={{ marginTop: '10px' }}>
{todo}
<button
onClick={() => handleDelete(index)}
style={{ marginLeft: '12px', color: 'red' }}
>
Delete
</button>
</li>
))}
</ul>
</div>
);
}
export default App;
Optional Enhancements
Once you’ve built the basic app, consider adding:
- Edit functionality for tasks
- Mark task as completed
- Save tasks to
localStorage
- Sort tasks by date or priority
- Break the app into components (
TodoItem
,TodoList
,InputForm
)
These improvements will teach you advanced concepts like props, lifting state up, and side effects with useEffect
.
Final Thoughts
Building a to-do app in React is a great way to gain hands-on experience with the framework. You learn how to manage state, handle user input, and work with lists dynamically — all of which are essential skills in modern front-end development.
Start small, experiment, and keep improving your app by adding new features. The more you build, the more confident you’ll become in using React effectively.

I’m Shreyash Mhashilkar, an IT professional who loves building user-friendly, scalable digital solutions. Outside of coding, I enjoy researching new places, learning about different cultures, and exploring how technology shapes the way we live and travel. I share my experiences and discoveries to help others explore new places, cultures, and ideas with curiosity and enthusiasm.