Project 1 — Todo App in React (Full Implementation)

🧭 Project Introduction

The Todo App is the most popular beginner project — but we will build it the professional way, not just a demo.

In this project, you will learn:

  • How to structure a real React project
  • How to add, edit, delete todos
  • How to manage state cleanly
  • How to build reusable components
  • How to apply best practices

🎯 Features of Our Todo App

✔ Add a todo
✔ View all todos
✔ Edit a todo
✔ Delete a todo
✔ Controlled input
✔ Clean UI logic
✔ Reusable components


📁 Project Folder Structure (Best Practice)

src/
 ├── components/
 │    ├── TodoForm.jsx
 │    ├── TodoItem.jsx
 │    └── TodoList.jsx
 ├── App.jsx
 ├── main.jsx
 └── index.css

👉 Simple, clean, and scalable.


🧠 State Design (Important)

We will store todos as an array of objects:

{
  id: number,
  text: string
}


🧩 Step 1: App.jsx (Main Container)

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

const App = () => {
  const [todos, setTodos] = useState([]);
  const [editTodo, setEditTodo] = useState(null);

  // Add Todo
  const addTodo = (text) => {
    setTodos([...todos, { id: Date.now(), text }]);
  };

  // Delete Todo
  const deleteTodo = (id) => {
    setTodos(todos.filter((todo) => todo.id !== id));
  };

  // Update Todo
  const updateTodo = (id, text) => {
    setTodos(
      todos.map((todo) =>
        todo.id === id ? { ...todo, text } : todo
      )
    );
    setEditTodo(null);
  };

  return (
    <div className="container">
      <h1>📝 Todo App</h1>

      <TodoForm
        addTodo={addTodo}
        editTodo={editTodo}
        updateTodo={updateTodo}
      />

      <TodoList
        todos={todos}
        deleteTodo={deleteTodo}
        setEditTodo={setEditTodo}
      />
    </div>
  );
};

export default App;


🧩 Step 2: TodoForm.jsx (Add & Edit Todos)

import { useEffect, useState } from "react";

const TodoForm = ({ addTodo, editTodo, updateTodo }) => {
  const [text, setText] = useState("");

  useEffect(() => {
    if (editTodo) {
      setText(editTodo.text);
    }
  }, [editTodo]);

  const handleSubmit = (e) => {
    e.preventDefault();

    if (!text.trim()) return;

    if (editTodo) {
      updateTodo(editTodo.id, text);
    } else {
      addTodo(text);
    }

    setText("");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Enter todo"
        value={text}
        onChange={(e) => setText(e.target.value)}
      />

      <button type="submit">
        {editTodo ? "Update" : "Add"}
      </button>
    </form>
  );
};

export default TodoForm;

✔ Controlled input
✔ Reusable for Add & Edit
✔ Clean logic


🧩 Step 3: TodoList.jsx (Render Todos)

import TodoItem from "./TodoItem";

const TodoList = ({ todos, deleteTodo, setEditTodo }) => {
  if (todos.length === 0) {
    return <p>No todos yet 🚀</p>;
  }

  return (
    <ul>
      {todos.map((todo) => (
        <TodoItem
          key={todo.id}
          todo={todo}
          deleteTodo={deleteTodo}
          setEditTodo={setEditTodo}
        />
      ))}
    </ul>
  );
};

export default TodoList;

✔ Handles empty state
✔ Uses reusable item component


🧩 Step 4: TodoItem.jsx (Single Todo)

const TodoItem = ({ todo, deleteTodo, setEditTodo }) => {
  return (
    <li className="todo-item">
      <span>{todo.text}</span>

      <div>
        <button onClick={() => setEditTodo(todo)}>
          Edit
        </button>
        <button onClick={() => deleteTodo(todo.id)}>
          Delete
        </button>
      </div>
    </li>
  );
};

export default TodoItem;

✔ Clean
✔ Focused
✔ Reusable


🎨 Step 5: Basic Styling (index.css)

body {
  font-family: Arial, sans-serif;
  background: #f4f4f4;
}

.container {
  max-width: 400px;
  margin: 40px auto;
  background: white;
  padding: 20px;
  border-radius: 5px;
}

form {
  display: flex;
  gap: 10px;
}

input {
  flex: 1;
  padding: 8px;
}

button {
  padding: 8px 12px;
  cursor: pointer;
}

.todo-item {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
}


🧠 Concepts Applied in This Project

✔ useState
✔ useEffect
✔ Controlled inputs
✔ Lifting state up
✔ Reusable components
✔ Clean folder structure


⚠ Common Improvements (Optional)

You can enhance this project by adding:

  • LocalStorage persistence
  • Checkbox for completed todos
  • Filters (All / Completed / Pending)
  • Tailwind or MUI styling

🎯 Best Practices Used

✅ No duplicate code
✅ Clear responsibilities
✅ Clean state updates
✅ Small focused components


🧠 Quick Recap

✔ Complete CRUD Todo App
✔ Real project structure
✔ Professional React patterns
✔ Beginner-friendly + scalable


🎉 Final Conclusion

🎉 Congratulations!
You have built your first real React project using best practices — not just a demo.

This Todo App proves you understand:

  • React fundamentals
  • Component architecture
  • State management
  • Clean code practices

🚀 What’s Next?

👉 Project 2 — Survey Form (Advanced Forms + Validation)

Leave a Comment