[React] 서버 데이터를 다루기 좋은 React Query 기본 사용법

2022. 9. 9. 05:23Front-end/React

 

React Query

React Query는 데이터 Fetching, 캐싱, 동기화, 서버 쪽 데이터 업데이트 등을 쉽게 만들어 주는 서버 상태 관리 라이브러리다. 기존에 Redux, Recoil과 같은 다양하고 훌륭한 상태 관리 라이브러리들이 있긴 하지만, 클라이언트 쪽의 데이터들을 관리하기에 적합할 순 있어도 서버 쪽의 데이터들을 관리하기에는 적합하지 않은 점들이 있어서 등장하게 되었다.


QueryClientProvider

  • 리액트 쿼리를 사용하기 위해 최상위 컴포넌트를 QueryClientProvider로 감싸준다.
  • 쿼리 인스턴스를 생성 후 client={queryClient} 작성해준다.
import { QueryClient, QueryClientProvider } from "react-query";

const queryClient = new QueryClient();

export const App = () => {
  return (
    <QueryClientProvider client={queryClient}>
      <Router />
    </QueryClientProvider>
  );
}

 

useQuery

import { useQuery } from "react-query";

const { data, isLoading, error } = useQuery(queryKey, queryFn, options);
// 주로 사용되는 세가지 반환 값 외에도 많은 값들이 있다.

 

QueryKey

  • QueryKey 를 기반으로 데이터 캐싱을 관리한다.
  • 문자열 또는 배열로 지정할 수 있다.
// 문자열
useQuery("getData", ...)
// 배열
useQuery(["getData"], ...)

쿼리가 변수에 의존하는 경우에는 QueryKey 에도 해당 변수를 추가해주어야한다.

const { data, isLoading, error } = useQuery(["getData", id], () => axios.get(`http://.../${id}`));

 

Query Functions

  • useQuery 의 두번째 인자에는 promise 를 반환하는 함수를 넣어주어야한다.
 useQuery("posts", getPosts);
 
 useQuery(["posts", userId], () => getPosts(userId));
 
 useQuery(["posts", userId], async () => {
   return await getPosts(userId);
 });

 

Query Options

  • 리액트 쿼리 공식 문서에 많은 쿼리 옵션에 대한 소개가 있지만, 자주 사용하는 몇가지만 알아보자.

 

enabled (boolean)

  • enabled는 쿼리가 자동으로 실행되지 않게 설정하는 옵션이다.
  • 아래의 코드는 id가 존재할 때만 쿼리 요청을 한다는 의미의 코드이다.
const { data } = useQuery(
  ["posts", id],
  () => getPosts(id),
  {
    enabled: !!id,
  }
);

 

retry (boolean | number | (failureCount: number, error: TError) => boolean)

  • retry 는 실패한 쿼리를 재시도하는 옵션으로, 미설정시 default로 세번 재시도 한다.
  • true로 설정하면 쿼리 실패시 무한으로 재시도하고 false로 설정하면 재시도를 하지 않는다.

 

staleTime (number | Infinity)

  • staleTime 은 데이터가 fresh 상태로 유지되는 시간이다. 해당 시간이 지나면 stale 상태가 된다.
  • default staleTime은 0이며, fresh 상태에서는 쿼리가 다시 mount 되어도 refetch되지 않는다.

 

cacheTime (number | Infinity)

  • cacheTime은 inactive 상태인 캐시 데이터가 메모리에 남아있는 시간이다. 이 시간이 지나면 캐시 데이터는 가비지 컬렉터에 의해 메모리에서 제거된다. default cacheTime 은 5분이다.

 

refetchOnMount (boolean | "always")

  • refetchOnMount 는 데이터가 stale 상태일 경우 마운트 시 마다 refetch를 실행하는 옵션이다.
  • default 설정 값은 true이며, always로 설정하면 마운트 시 마다 매번 refetch를 실행한다.

 

refetchOnWindowFocus (boolean | "always")

  • refetchOnWindowFocus 는 데이터가 stale 상태일 경우 윈도우가 포커스 될때마다 refetch를 실행하는 옵션이다.
  • 브라우저에서 다른 탭을 눌렀다가 다시 원래 보던 탭을 눌렀을 때도 이 경우에 해당하며, 개발자 도구창을 클릭했다가  다시 페이지를 클릭하는 경우에도 해당한다.
  • default 설정 값은 true이며, always로 설정하면 항상 윈도우가 포커스 될때마다 refetch를 실행한다.
// 유저 정보를 불러오는 쿼리
const { data: userInfo } = useQuery(
  ["userInfo"],
  getUserInfo,
  {
    refetchOnWindowFocus: true, // 윈도우 포커스 마다 refatch
    staleTime: 1000 * 30, // fresh 상태를 30초 동안 유지
  }
)

만약 QueryClient의 default 옵션 설정으로 refetch 기능들을 false로 설정했을 경우에는 refetch 기능이 실행되지 않으며,  그런 경우에는 쿼리 옵션에서 true로 설정하면 옵션이 설정된 쿼리에만 refetch 기능이 실행된다. 그리고 fresh 상태인 30초 동안은 다른 윈도우와 포커스를 왔다 갔다해도 refetch를 실행하지 않는다.

 

refetchOnReconnect (boolean | "always")

  • refetchOnReconnect는 데이터가 stale 상태일 경우 재연결될 때 refetch를 실행하는 옵션이다.
  • default 설정 값은 true이며, always로 설정하면 매번 재연결될때마다 refetch를 실행한다.

 

onSuccess ((data: TDdata) => void)

  • onSuccess는 쿼리 성공 시 실행되는 함수이며, 매개변수 data는 성공 시 서버에서 넘어오는 response 값이다.

 

onError ((error: TError) => void)

  • onError는 쿼리 실패 시 실행되는 함수로 매개변수로 에러 값을 받을 수 있다.
const { data: userInfo } = useQuery(
  ["userInfo"],
  getUserInfo,
  {
    refetchOnWindowFocus: true,
    staleTime: 30 * 1000, // 30초
    onError: (error) => {
      if (error.response?.data.code === 401) {
        //...
      }
    },
  }
)


onSettled ((data?: TData, error?: TError) => void)

  • onSettled는 쿼리가 성공해서 성공한 데이터가 전달되거나, 실패해서 에러가 전달될 때 실행되는 함수이다.
  • 매개변수로 성공 시엔 성공 데이터, 실패 시에는 에러가 전달된다.

 

initialData (TData | () => TData)

  • initialData를 설정하면 쿼리 캐시의 초기 데이터로 사용된다. (쿼리가 아직 생성되지 않았거나 캐시되지 않았을 때)
  • staleTime이 설정되지 않은 경우 초기 데이터는 기본적으로 stale 상태로 간주한다.

 

 

 

반응형