티스토리 뷰
타입스크립트를 처음 해보는데.. 처음 공부하면서 투두리스트 만들기를 해보았다.
프로젝트 생성
프로젝트 생성
yarn create vite ts-todo-list --template react-ts
json-server 설치
yarn add json-server
전체 코드
- todos.ts
export type Todo = {
id: string;
title: string;
completed: boolean;
};
/** 조회 */
export const getTodos = async (): Promise<Todo[]> => {
const res = await fetch("http://localhost:4000/todos");
const data = await res.json();
return data;
};
/** 등록 */
export const postTodo = async (newTodo: Todo): Promise<void> => {
await fetch("http://localhost:4000/todos", {
method: "POST",
body: JSON.stringify(newTodo),
});
};
/** 삭제 */
export const deleteTodo = async (id: Todo["id"]): Promise<void> => {
await fetch(`http://localhost:4000/todos/${id}`, {
method: "DELETE",
});
};
- App.tsx
import { useEffect, useState } from "react";
import "./App.css";
import { deleteTodo, getTodos, postTodo } from "./api/todos";
import TodoList from "./components/TodoList";
import { type Todo } from "./api/todos";
function App() {
const [todoList, setTodoList] = useState<Todo[]>([]);
const [title, setTitle] = useState<string>("");
useEffect(() => {
getTodos().then((data) => {
setTodoList(data);
});
}, []);
const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
};
const handleAddTodo = async () => {
const newTodo: Todo = {
id: crypto.randomUUID(),
title,
completed: false,
};
await postTodo(newTodo);
setTodoList((prev) => [...prev, newTodo]);
setTitle("");
};
const handleDeleteTodo = async (id: Todo["id"]) => {
await deleteTodo(id);
setTodoList((prev) => prev.filter((todo) => todo.id !== id));
};
return (
<>
<TodoList todoList={todoList} handleDeleteTodo={handleDeleteTodo} />
<input type="text" value={title} onChange={handleTitleChange} />
<button onClick={handleAddTodo}>등록</button>
</>
);
}
export default App;
- TodoList.tsx
import React from "react";
import TodoItem from "./TodoItem";
import { type Todo } from "../api/todos";
type TodoListProps = {
todoList: Todo[];
handleDeleteTodo: (id: Todo["id"]) => void;
};
const TodoList = ({ todoList, handleDeleteTodo }: TodoListProps) => {
return (
<>
{todoList.map((todo) => {
return (
<TodoItem
key={todo.id}
todo={todo}
handleDeleteTodo={handleDeleteTodo}
/>
);
})}
</>
);
};
export default TodoList;
- TodoItem.tsx
import React from "react";
import { type Todo } from "../api/todos";
type TodoItemProps = {
todo: Todo;
handleDeleteTodo: (id: Todo["id"]) => void;
};
const TodoItem = ({ todo, handleDeleteTodo }: TodoItemProps) => {
return (
<>
<div>
<p>{todo.title}</p>
<p>{`${todo.completed}`}</p>
<button
onClick={() => {
handleDeleteTodo(todo.id);
}}
>
삭제
</button>
</div>
<hr />
</>
);
};
export default TodoItem;
- db.json
{
"todos": [
{
"id": "d3",
"title": "title",
"completed": false
},
{
"id": "0097cff4-3a30-4eff-b9a1-bfb64edf3525",
"title": "타입스크립트 공부",
"completed": false
}
]
}
최근에 올라온 글
- Total
- Today
- Yesterday
링크