Day15 要撰寫的是待辦清單,並把資料存進瀏覽器的 LocalStorage
const [todos, setTodos] = useState<Todo[]>(() => {
const storedTodos = localStorage.getItem("todos");
return storedTodos ? JSON.parse(storedTodos) : [];
});
const [newTodo, setNewTodo] = useState<string>("");
const updateTodos = (newTodos: Todo[]) => {
localStorage.setItem("todos", JSON.stringify(newTodos));
setTodos(newTodos);
};
const addTodo = () => {
if (!newTodo.trim()) {
return;
}
const newTodos: Todo[] = [
...todos,
{ id: Date.now(), text: newTodo, done: false },
];
updateTodos(newTodos);
setNewTodo("");
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
addTodo();
}
};
const toggleTodo = (id: number) => {
const newTodos = todos.map((todo) =>
todo.id === id ? { ...todo, done: !todo.done } : todo
);
updateTodos(newTodos);
};
const removeTodo = (id: number) => {
const newTodos = todos.filter((todo) => todo.id !== id);
updateTodos(newTodos);
};
return (
<div className="max-w-md mx-auto mt-10 p-6 bg-white rounded-lg shadow-xl">
<h1 className="text-2xl font-bold mb-4">Todo List</h1>
<div className="mb-4">
<input
type="text"
value={newTodo}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setNewTodo(e.target.value)
}
onKeyDown={handleKeyDown}
placeholder="Add a new todo"
className="w-full p-2 border border-gray-300 rounded"
/>
<button
type="button"
onClick={addTodo}
className="mt-2 w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600"
>
Add Todo
</button>
</div>
<ul>
{todos.map((todo) => (
<li
key={todo.id}
className="flex items-center justify-between p-2 border-b"
>
<p
className={`flex-grow cursor-pointer ${
todo.done ? "line-through text-gray-500" : ""
}`}
onClick={() => toggleTodo(todo.id)}
>
{todo.text}
</p>
<button
type="button"
onClick={() => removeTodo(todo.id)}
className="ml-2 text-red-500 hover:text-red-700"
>
Delete
</button>
</li>
))}
</ul>
</div>
);
}