📌 주제 : 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랑 어색한 사이....