Description

Solution

Submissions

Overview

  • Local state: input text & todo list
    • We keep two independent bits of state: the current text in the input box and the array holding todos.

      javascript

      const [text, setText] = useState(""); const [todos, setTodos] = useState([]);
  • Adding a todo immutably
    • Trim the text; if it isn’t empty, copy the array and append the new item, then clear the input.

      javascript

      const handleAdd = () => { const trimmed = text.trim(); if (!trimmed) return; setTodos([...todos, trimmed]); setText(""); };
  • Removing a specific item
    • Create a new array that filters out only the clicked index.

      javascript

      const handleRemove = (idx) => { setTodos(todos.filter((_, i) => i !== idx)); };
  • Rendering UI
    • A <ul> whose <li> children map over todos, each with a Remove button.

      javascript

      <ul data-testid="todo-list" className="space-y-2"> {todos.map((t, i) => ( <li key={i} data-testid="todo-item" className="flex justify-between items-center bg-gray-100 px-3 py-2 rounded" > <span>{t}</span> <button data-testid="remove-btn" onClick={() => handleRemove(i)} className="text-sm font-semibold text-red-600" > ✕ </button> </li> ))} </ul>
These four pieces—the state, add/remove handlers, and render logic—cover the essential mechanics for a fully working, immutably updated todo list.
App.js
import TodoList from "./TodoList";

export default function App() {
  return (
    <div className="min-h-screen bg-gray-50 p-4 flex justify-center">
      <TodoList />
    </div>
  );
}

Browser

Console

Test Cases

Submit

JavaScript Console

console.log()
statements will appear here

Run Tests

Click the 'Run' button below to run the tests
in the run.test.js file

Submit

Click the 'Submit' button below to submit your solution

Open browser consoleTests