How to Build Your First Todo App in React

Introduction

React is one of the most popular JavaScript libraries for building interactive user interfaces. Created and maintained by Facebook, React enables developers to craft scalable, reusable, and efficient UI components that power modern web applications. If you’re new to React, a Todo App is an excellent first project—simple to grasp yet powerful enough to showcase React’s primary features such as components, props, state management, and event handling.

In this article, we’ll build your first Todo App in React step by step. By the end, you’ll have a working app and a solid understanding of essential React concepts and ecosystem basics.

Prerequisites

  • Basic understanding of JavaScript (ES6+)
  • Node.js and npm installed
  • A code editor (VS Code recommended)
  • Familiarity with basic HTML and CSS

Setting Up the Project

We’ll use create-react-app to keep things simple:

npx create-react-app todo-app
cd todo-app
npm start

This starts a dev server at http://localhost:3000/.

Project Structure Overview

todo-app/
 ├── node_modules/
 ├── public/
 ├── src/
 │   ├── App.js
 │   ├── index.js
 │   └── App.css
 ├── package.json

We’ll primarily work in the src folder.

Creating the Todo App Layout

A basic Todo App includes:

  • An input field to add tasks
  • A list of todos
  • Options to mark tasks complete or delete them

We’ll split the app into components:

  • App.js – Main container
  • TodoList.js – Displays all todos
  • TodoItem.js – Single todo item
  • TodoForm.js – Input form for adding todos

Managing State with React Hooks

Use the useState hook to manage the todos in App.js:

import React, { useState } from "react";
import TodoForm from "./TodoForm";
import TodoList from "./TodoList";

function App() {
  const [todos, setTodos] = useState([]);

  return (
    

My Todo App


  );
}

export default App;

todos holds all tasks.

Adding New Todos

TodoForm.js:

import React, { useState } from "react";

function TodoForm({ todos, setTodos }) {
  const [input, setInput] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    if (input.trim() === "") return;
    setTodos([...todos, { id: Date.now(), text: input, completed: false }]);
    setInput("");
  };

  return (
    

setInput(e.target.value)} placeholder="Add a new task..." /> Add


  );
}

export default TodoForm;

Displaying Todos

TodoList.js:

import React from "react";
import TodoItem from "./TodoItem";

function TodoList({ todos, setTodos }) {
  return (
    
  • {todos.map((todo) => ( ))}

  );
}

export default TodoList;

Marking Todos as Completed & Deleting

TodoItem.js:

import React from "react";

function TodoItem({ todo, setTodos }) {
  const toggleComplete = () => {
    setTodos((prevTodos) =>
      prevTodos.map((t) =>
        t.id === todo.id ? { ...t, completed: !t.completed } : t
      )
    );
  };

  const deleteTodo = () => {
    setTodos((prevTodos) => prevTodos.filter((t) => t.id !== todo.id));
  };

  return (
    
      {todo.text}
      
        {todo.completed ? "Undo" : "Complete"}
      
      Delete
    
  );
}

export default TodoItem;

Improving the App

  • Persistence with localStorage – Save tasks across refreshes
  • Filters – Show all, completed, or active tasks
  • Clear All – Remove all tasks at once

Example: localStorage persistence

import React, { useState, useEffect } from "react";

function App() {
  const [todos, setTodos] = useState(() => {
    const localData = localStorage.getItem("todos");
    return localData ? JSON.parse(localData) : [];
  });

  useEffect(() => {
    localStorage.setItem("todos", JSON.stringify(todos));
  }, [todos]);

  // ...rest of the App component
}

Final Code Structure

  • App.js – Main app container
  • TodoForm.js – Input form for adding tasks
  • TodoList.js – Renders all todos
  • TodoItem.js – Single todo with complete/delete
  • App.css – Styling

Testing the App

  • Add, complete, and delete tasks
  • Refresh the page to verify localStorage persistence
  • Test edge cases (empty input, deleting all)

Real-World Use of React

Your Todo App mirrors patterns used in large-scale apps. Many well-known brands rely on React for their UI:

  • Facebook – Where React was born
  • Netflix – Fast, responsive interfaces
  • Airbnb – Interactive booking experiences
  • Instagram – React-driven UI at scale

Conclusion & Next Steps

Congrats—your first React Todo App is complete! You learned how to:

  • Structure a React project
  • Create components and pass props
  • Manage state with hooks
  • Handle adding, completing, and deleting tasks
  • Enhance apps using localStorage and basic filters

Next steps to level up:

  • Adopt Context API or Redux for advanced state management
  • Use TypeScript with React for safer code
  • Integrate a backend API for persistent storage

Ready to take your React journey further? Explore the official React documentation and consider expert guidance from The One Technologies.

Enjoyed this article? Stay informed by joining our newsletter!

Comments

You must be logged in to post a comment.

About Author