티스토리 뷰

typescript

[typescript] todo list 만들기

developer jungminji 2024. 9. 25. 04:04

타입스크립트를 처음 해보는데.. 처음 공부하면서 투두리스트 만들기를 해보았다.

 

프로젝트 생성

프로젝트 생성

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
링크