[TIL] TypeScript로 To Do List 만들기

·2023년 12월 18일
0

TIL

목록 보기
57/85
post-thumbnail

📌 주제 : Todolist를 Typescript로 만들어 봅시다.

  • 레벨1 : React 이용 Todolist
  • 레벨2 : RTK 이용 Todolist
  • 레벨3 : RTK + json-server 이용 Todolist
  • 레벨4 : RTK + redux thunk 이용 Todolist
  • 레벨5 : RTK + react-query 이용 Todolist
    레벨1 ~ 레벨5 중 하나를 선택하여 TypeScript 버전으로 작성합니다.

📌 필수 구현 사항(모든 구현 사항은 Typescript로 작성)

  • Todo 항목 추가 하기
    • 사용자가 새로운 Todo 항목을 입력하고 추가 할 수 있는 기능.
  • Todo 항목 목록 표시 기능
    • 각 Todo 하목은 고유 식별자를 가짐
  • Todo 삭제 하기
    • 삭제 시 사용자에게 삭제 확인 요청
  • Todo 완료 상태 표시 기능
    • 사용자가 Todo 항목을 완료했음을 표시

지난 번에 했던 투두리스트를 typeScript로 수정하는 것이 이번 과제였다.
나는 다섯개의 레벨 중 lv1, lv2, lv5 를 했다. (lv5에 json-sever가 들어있어서 lv3도 했다고 볼 수 있다.)

지겹게 만들었던 투두리스트이지만, 타입스크립트로 하려니 생소하고.. 마냥 쉽지만은 않았다.

그리고 이번에는 react-query 사용하는 부분을 useTodos 라는 커스텀 훅으로 만들어서 사용해 보았다. 그랬더니 코드가 훨씬 간결해졌다.

import {
  addTodoItem,
  deleteTodoItem,
  getTodos,
  updateTodoItem,
} from "../api/todos";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";

const QUERY_KEY = "todos";

export const useTodos = () => {
  const queryClient = useQueryClient();

  const {
    data: todos,
    isLoading,
    error,
  } = useQuery<TodoType[]>({
    queryKey: [QUERY_KEY],
    queryFn: getTodos,
  });

  const addTodoMutation = useMutation({
    mutationFn: addTodoItem,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: [QUERY_KEY] });
    },
  });

  const updateTodoMutation = useMutation({
    mutationFn: updateTodoItem,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: [QUERY_KEY] });
    },
  });

  const deleteTodoMutation = useMutation({
    mutationFn: deleteTodoItem,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: [QUERY_KEY] });
    },
  });

  return {
    todos,
    isLoading,
    error,
    addTodo: addTodoMutation.mutate,
    updateTodo: updateTodoMutation.mutate,
    deleteTodo: deleteTodoMutation.mutate,
  };
};
//TodoList.tsx
const TodoList = ({ isDone }: Props) => {
  const { todos = [], isLoading, error } = useTodos(); // 이렇게 꺼내어 쓴다.

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  return (
    <>
      <StState>{isDone ? "Done..!🎉" : "Working..!🔥"}</StState>
      <StTodoList>
        {todos
          .filter((todo) => todo.isDone === isDone)
          .map((todo) => (
            <Todo todo={todo} key={todo.id} />
          ))}
      </StTodoList>
    </>
  );
};

그리고 이전에 TodoType이 필요한 파일마다 type alias를 통해 선언해주었는데, 그러다 보니 불필요한 코드 중복이 많았다. 이를 global.d.ts 파일에 선언해주면 중복으로 선언하지 않고 (따로 import 하지도 않고..!!!) 사용할 수 있다는 것을 알았다.

// src/types/global.d.ts
type TodoType = {
  id: string;
  title: string;
  content: string;
  isDone: boolean;
};

과제는 화요일에 주어졌으나, 강의 듣고.. typeScript에 약간 발을 담궈보느라 과제를 시작한 건 금요일이었다. 다행히 (?) 하루만에 lv5까지 구현을 해볼 수 있었다. 근데 아직도 typeScript랑 어색한 사이....

profile
느리더라도 조금씩, 꾸준히

0개의 댓글