Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

나 개발자 할래요

2024.09.24 본문

개발자 되는 법.../TIL...

2024.09.24

개발_자 2024. 9. 25. 02:12

Todo List 과제

todo.ts

export type Todo = {
	id: string;
	title: string;
	completed: boolean;
};

export async function getTodos(): Promise<Todo[]> {
	const res = await fetch("http://localhost:4000/todos");
	const data = await res.json();

	return data;
}

getTodos().then(console.log);

 

App.tsx

import { useEffect, useState } from "react";
import { getTodos, type Todo } from "./todo";

type ToggleTodo = Omit<Todo, "title">;

function App() {
	const [todoList, setTodoList] = useState<Todo[]>([]);
	useEffect(() => {
		getTodos().then((data) => setTodoList(data));
	}, []);

	const [title, setTitle] = useState("");

	const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
		setTitle(e.target.value);
	};
	const handleAddTodo = async () => {
		if (title === "") {
			return;
		}

		const newTodo: Todo = {
			id: crypto.randomUUID(),
			title,
			completed: false,
		};

		await fetch("http://localhost:4000/todos", {
			method: "POST",
			body: JSON.stringify(newTodo),
		});

		setTodoList((prev) => [...prev, newTodo]);
		setTitle("");
	};

	const handleDeleteTodo = async (id: Todo["id"]) => {
		await fetch(`http://localhost:4000/todos/${id}`, {
			method: "DELETE",
		});
		setTodoList((prev) => prev.filter((todo) => todo.id !== id));
	};

	const handleToggleTodo = async ({ id, completed }: ToggleTodo) => {
		await fetch(`http://localhost:4000/todos/${id}`, {
			method: "PATCH",
			body: JSON.stringify({
				completed: !completed,
			}),
		});

		setTodoList((prev) =>
			prev.map((todo) => {
				if (todo.id === id) {
					return {
						...todo,
						completed: !completed,
					};
				}
				return todo;
			})
		);
	};

	return (
		<>
			<h2>Todo List</h2>
			<input type="text" value={title} onChange={handleTitleChange} />
			<button onClick={handleAddTodo}>Add Todo</button>
			<TodoList
				todoList={todoList}
				onDeleteClick={handleDeleteTodo}
				onToggleClick={handleToggleTodo}
			/>
		</>
	);
}

type TodoListProps = {
	todoList: Todo[];
	onDeleteClick: (id: Todo["id"]) => void;
	onToggleClick: (ToggleTodo: ToggleTodo) => void;
};
function TodoList({ todoList, onDeleteClick, onToggleClick }: TodoListProps) {
	return (
		<ul>
			{todoList.map((todo) => (
				<TodoItem
					key={todo.id}
					{...todo}
					onDeleteClick={onDeleteClick}
					onToggleClick={onToggleClick}
				/>
			))}
		</ul>
	);
}

type TodoItemProps = Todo & {
	onDeleteClick: (id: Todo["id"]) => void;
	onToggleClick: (ToggleTodo: ToggleTodo) => void;
};
function TodoItem({
	id,
	title,
	completed,
	onDeleteClick,
	onToggleClick,
}: TodoItemProps) {
	return (
		<li style={{ alignItems: "center" }}>
			<span
				style={{ textDecoration: completed ? "line-through" : "none" }}
			>
				{title}
			</span>
			<button onClick={() => onToggleClick({ id, completed })}>
				{completed ? "undo" : "Complete"}
			</button>
			<button onClick={() => onDeleteClick(id)}>Delete</button>
		</li>
	);
}

export default App;​

 

 

어우 개념 정리는 1회독 하고 하겠습니다.

'개발자 되는 법... > TIL...' 카테고리의 다른 글

2024.09.26  (0) 2024.09.26
2024.09.25  (5) 2024.09.26
2024.09.23  (0) 2024.09.23
2024.09.21  (0) 2024.09.21
2024.09.20  (0) 2024.09.21