원티드 프리온보딩 Todolist 만들기 회고

Nak·2023년 1월 20일
0
post-thumbnail

원티드 프리온보딩 Todolist만들기 회고

원티드 프리온보딩 1월에 시작한 todolist를 사전과제로 제출했었다.

typescript,CRA를 이용해서 상태관리는 props로 넘겨주는 형태로 개발했었다.

구조 문제

처음 강의를 들었을 때 폴더 구조를 쉽게 구성해야 다른사람이 보기도 쉽고
내가 나중에 코드를 확인하려고 했을 때 쉽게 찾기 위해서라고 배웠다.

처음 폴더 구조는 src안에 todo auth 폴더로 나눠놨었는데,

src
ㄴcomponent
ㄴhooks
ㄴpages
ㄴstyles
ㄴtypes
ㄴutil

보기 좋게 변경했다.
폴더 구조를 이렇게 변경 하니까 다른 사람이 보기도 쉽고,
내가 나중에 코드를 확인 하고 싶을 때 더 쉽게 찾을 수 있을 것 같았다.

상태관리를 위한 프롭스

프롭스로 넘겨줄때 type을 props의 타입까지 지정을 해줘서 보내줬다.

interface Todo{
id :string;
content:string;
title:string;
onDelete: (id: string) => void;

상태관리를 useState로 하고, todolist를 렌더링을 시켜주기 위해서
이런식으로 타입을 만들어서 todoitem에 프롭스로 넘겨주었다.

하지만 필요없는 타입들을 너무 많이 만들었고, 상태관리라이브러리를 사용 하면 더 클린한 코드를 만들 수 있다고 생각이 들었다.

react-query 도입

위에서 본 문제를 해결 하기 위해서 react-query 서버상태관리를 도입했다.

react-query는 서버의 값을 클라이언트에 가져오거나, 캐싱, 값 업데이트, 에러핸들링 등 비동기 과정을 더욱 편하게 하는데 사용한다.

react-query를 사용한 이유

  • 캐싱
  • get을 한 데이터에 대해 update를 하면 자동으로 get을 다시 수행.
  • 데이터가 오래 되었다고 판단되면 다시 get호출(invalidateQueries)
  • 동일 데이터 여러번 요청하면 한번만 요청한다.(옵션으로 변경 가능)
  • 비동기 과정을 선언적으로 관리 가능.

react-query 사용 방법

app.js--------------
import { BrowserRouter as Router } from "react-router-dom";
import ReactDOM from "react-dom/client";
import App from "./App";
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
const queryClient = new QueryClient();

root.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
    <QueryClientProvider client={queryClient}>
      <Router>
        {/* <ReactQueryDevtools initialIsOpen={true} /> */} //리엑트 쿼리 데브 툴스.
        <App />
      </Router>
    </QueryClientProvider>
  </React.StrictMode>
);

useQuery

useQuery는 데이터를 get하기 위한 함수이며 argument(매개변수)를 필요로한다
우선 내가 사용한 방식은 유니크 키(쿼리를 identify할 중복되지 않는키)ex)"todos"
만들어둔 Promise를 반환하는 함수(api)를 매개변수로 넣었다.
리액트 쿼리를 사용하면 useEffect, useState 없이 구현할 수 있다

--- userTodosApi.ts

const getTodo = async () => {
  const res = await baseAxios.get("/todos");
  return res.data.data;
};

---- queries
import { useQuery } from "react-query";
import { getTodo } from "../userTodosApi";

function useUserTodoList() {
  const { data: Todo, status } = useQuery("todos", getTodo);

  return { Todo, status };
}
export default useUserTodoList;

----todos.tsx
  const { Todo, status } = useUserTodoList();
  
	    {Todo.map((todo: Todo) => {
          return (
            <div>
              <TodoItem
                key={todo.id}
                title={todo.title}
                content={todo.content}
                id={todo.id}
              ></TodoItem>
            </div>

useMutation

생성/수정/삭제 시에 사용하는 api입니다.
useMutation은 인자로 mutation함수와 options를 받습니다.
mutation함수는 생성/수정/삭제 api를 호출 함수로 할당합니다.
options에는 성공,실패 등 다양한 콜백 함수를 할당 할 수 있습니다.

매번 목록을 최신화하는 것이 번거롭다. 이때 사용할 수 있는 녀석이 있다.
invalidateQueries다.
invalidateQueries는 쿼리들을 stale로 상태를 변경하고 refetch 시킨다.
Stale: 서버 / 클라이언트의 정보가 동일함을 보장할 수 없는(신선하지 않은) 상태입니다
사용 하기 위해서는 queryClient를 임포트 해야한다.

--- mutation.ts
const TodoMutation = () => {
  const queryClient = useQueryClient();
  const { mutate: createMutations } = useMutation(
    (id: Record<string, string>) => createTodo(id),
    {
      onSuccess: () => {
        queryClient.invalidateQueries("todos");
      },
    }
  );
  const { mutate: deleteMutation } = useMutation(
    (id: string) => deleteTodo(id),
    {
      onSuccess: () => {
        queryClient.invalidateQueries("todos");
      },
    }
  );
  const { mutate: updateMutation } = useMutation(
    (todo: Todo) => updateTodo(todo),
    {
      onSuccess: () => {
        queryClient.invalidateQueries("todos");
      },
    }
  );

  return { createMutations, deleteMutation, updateMutation };
};

export default TodoMutation;

---todos.tsx-----------
  const { createMutations } = TodoMutation();

const onSubmit = useCallback(
    (e: React.FormEvent<HTMLFormElement>) => {
      e.preventDefault();
      const data = {
        title: titleRef.current!.value,
        content: contentsRef.current!.value,
      };
      createMutations(data);
      titleRef.current!.value = "";
      contentsRef.current!.value = "";
    },
    [createMutations]
  );

react-query에는 사용 가능한 함수,매개변수가 많다.
공식 홈페이지를 찾아보면 좋다.

https://tanstack.com/query/v4/docs/react/reference/useQuery

기술스택 : typescript,CRA,react-router,MUI,styled-components,react-query

깃허브

0개의 댓글