[TIL] React Query 사용 (TS)

대빵·2023년 12월 15일
1

React Query란?

웹 서비스를 요청하고, 응답받은 데이터를 관리하는데 도움이 되는 라이브러리이다.
React Query가 실제로 서비스 요청을 하는 것은 아니다.(이 부분은 여전히.. fetch나 axios와 같은 라이브러리를 사용해야 한다.)

React Query를 사용하면 컴포넌트 라이프 사이클에 맞춰 적절한 타이밍에 서비스 요청을 지시할 수 있다. 또, 요청 응답 데이터를 상태(state)로 설정하거나 서비스 요청을 위한 상태 변수를 지정 할 수 도 있다.

서버상태

클라이언트 사이드 상태(Client-Side State)

클라이언트 사이드 상태는 사용자의 브라우저 내에서 관리되는 상태이다. 리액트 컴포넌트의 useState또는 상태 관리 라이브러리(ex. Redux, MobX, Recoil)를 통해 관리된다.

특징

  • 로컬데이터 : 주로 UI 컴포넌트 상태, 사용자 입력, 토글 상태와 같이 로컬에서만 필요한 데이터를 관리한다.
  • 성능 : 네트워크 지연 없이 빠르게 상태를 변경하고 반응할 수 있다.
  • 수명 주기 : 클라이언트 사이드 상태는 페이지를 새로고침하거나 어플리케이션을 종료할 때 초기화되는 경향이 있다.
  • 예시 : 사용자가 입력한 폼 데이터, UI 컴포넌트의 보이기/숨기기 상태등등...

서버 사이드 상태(Server-Side State)

서버 사이드 상태는 서버에 저장되고 관리되는 데이터를 말한다. 이는 데이터베이스, 파일 시스템, 서버의 메모리 등에 저장될 수 있다.

특징

  • 중앙 집중식 데이터 : 사용자 정보, 어플리케이션 설정, 대규모 데이터셋 등 여러 세션 또는 사용자 간에 공유되어야 하는 데이터를 관리한다.
  • 지속성 : 데이터가 서버에 저장되므로, 클라이언트의 상태가 초기화되거나 변경되어도 영구적으로 유지된다.
  • 동기화와 일관성 : 클라이언트에서 서버로 데이터를 요청하거나 업데이트하면서 발생하는 네트워크 지연과 데이터 동기화에 대한 고려가 필요하다.
  • 예시 : 사용자 계정 정보, 어플리케이션의 공유 설정, 대규모 데이터셋등등..

React Query 설치

npm install react-query
yarn add react-query

TyepScript사용을 위한 Type을 포함하고 있으므로 별도의 패키지 설치는 필요가 없다.

React Query 사용

QueryClientProvider

데이터를 읽어오는 기능(QueryClient)을 어플리케이션 전체에 주입하도록 하는 API

참고로 react-query에서 devtools를 지원한다.

import { QueryClient, QueryClientProvider } from "react-query";

export default function App() {
  const queryClient = new QueryClient();

  return (
    <QueryClientProvider client={queryClient}>
  	  <ReactQueryDevtools initialIsOpen={true} />
      <App />
    </QueryClientProvider>
  );
}

useQuery

import { useQuery } from "react-query";
import { getTodos } from "../api/todos";

function App() {
	const { isLoading, isError, data } = useQuery("todos", getTodos, {
    staleTime: Infinity,
  });
  
  if (isLoading) {
    return <div>로딩중...</div>;
  }

  if (isError) {
    return <p>오류가 발생하였습니다...!</p>;
  }
  
  return (
    <ul>
      {data
        ?.filter((todo: TodoType) => {
          return todo.isDone === isDone;
        })
        .map((todo: TodoType) => {
          return (
            ~~~
          );
        })}
    </ul>
}

Mutation

query와 다르게 mutation은 CUD에서 사용된다.

import { useMutation, useQueryClient } from "react-query";
import { deleteTodo, patchTodo } from "../api/todos";

function App() {
  const queryClient = useQueryClient();
  
  // update mutation~~
  const { mutate: updateMutate } = useMutation("todos", patchTodo, {
    onSuccess: () => {
      queryClient.invalidateQueries("todos");
    },
  });

  // delete mutation~~
  const { mutate: deleteMutate } = useMutation("todos", deleteTodo, {
    onSuccess: () => {
      queryClient.invalidateQueries("todos");
    },
  });
  
  const isDoneBtn = (todo: TodoType) => {
    updateMutate(todo);
  };

  const deletBtn = (id: number) => {
    deleteMutate(id);
  };
  
  return (
    <ul>
      {data
        ?.filter((todo: TodoType) => {
          return todo.isDone === isDone;
        })
        .map((todo: TodoType) => {
          return (
            ~~~
          );
        })}
    </ul>
}

mutation.mutate(인자)

  • 인자는 반드시 한 개의 변수 또는 객체이여야 한다.
  • mutation.mutate(인자1, 인자2) -> 오류

결과를 객체(object 형태)갖고 있다.

결과물 객체는 항상 어느 상태 중 하나에 속한다

  • isldle

  • isLoding

  • isError

  • error 객체를 항상 품고 있음을 명심해야 한다.

  • isSuccess(query에만 있는게 아니다)

  • data 객체를 항상 품고 있을을 명심해야 한다.

0개의 댓글