react

[react-query]@tanstack/react-query를 사용해보자

냠냠맨 2023. 6. 5. 16:11

😯@tanstack/react-query를 사용하는 이유

 

리액트쿼리는 강력한 데이터페칭도구입니다.

비동기 상태 관리를 도와주고 로딩, 에러처리, 리페칭, 캐싱 등

개발자가 생각하기 귀찮은 문제들을 대신 해결해주며

개발자는 무엇을 할것인지에 더 초점을 맞출 수 있도록 도와주는 라이브러리입니다.

 

비슷한 역할을 하는 라이브러리로 ReduxToolkit이 제공하는

RTK Query가 있습니다.

RTK Query에 대한 사용법이 궁금하신 분들은 아래 링크를 참고하세요

https://xionwcfm.tistory.com/279

 

예제와 함께 TS ReduxToolkit Query Slow start

ReduxToolkit Query에 대해서 잘 정리된 문서 / 영상을 찾아보기가 굉장히 힘들었고 특히 한국어로 되어있는 양질의 문서는 거의 전멸에 가까운 수준이었습니다. 그나마.. 영미권 유튜브로 눈길을 돌

xionwcfm.tistory.com

 

개인적으론 처음 사용법을 배우는 입장에서는

ReactQuery쪽이 압도적으로 쉽다는 생각이 듭니다.

 

이 포스트에서는 @tanstack/react-query-devtools의 사용방법과

@tanstack/react-query의 기초적인 사용법을 다루도록 합니다.

모든 예제는 tanstack.com을 참고하여 작성되었습니다.


🤐설치 방법

$ npm i @tanstack/react-query
# or
$ pnpm add @tanstack/react-query
# or
$ yarn add @tanstack/react-query

react-query의 설치방법은 다음과 같습니다.

$ npm i @tanstack/react-query-devtools
# or
$ pnpm add @tanstack/react-query-devtools
# or
$ yarn add @tanstack/react-query-devtools

다음은 devtools의 설치방법입니다.

devtools는 개발환경에서만 설치해도 괜찮으니 -D 옵션을 주어도 좋습니다.


🥰먼저 Provider를 감싸주자.

https://tanstack.com/query/latest/docs/react/examples/react/simple

 

React Query Simple Example | TanStack Query Docs

An example showing how to implement Simple in React Query

tanstack.com

만약 이미 완성된 코드샌드박스를 참고하고싶거나

React로 프로젝트를 만들고 있는 경우 위 링크를 참고해주세요

 

폴더를 나누어 작업하고 싶거나 Next.js와 app라우터를 사용하고 있다면

제 코드를 따라와주시면 될 것 같습니다.


😤src/components/Providers.tsx

'use client';

import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { FC } from 'react';

interface ProvidersProps {
  children: React.ReactNode;
}

const Providers: FC<ProvidersProps> = ({ children }) => {
  const queryClient = new QueryClient();

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

export default Providers;

먼저 Provider를 사용해주어야 할 것입니다.

리액트쿼리는 QueryClientProvider를 제공합니다.

Provider를 리액트쿼리를 사용하길 원하는 컴포넌트 사이에 감싸주면 되는데

props로 client를 전달해주어야합니다.

이 cleint prop에 전달할 값은 QueryClient의 인스턴스를 전달해주는것으로 만족시킬 수 있습니다.

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

 

또한 reactquery는 자체적인 개발자도구를 제공해줍니다.

QueryClientProvider의 내부에 전달해주면 사용할 수 있고

공식문서에 따르면 최대한 상단에 위치시켜주는 것을 권장합니다.

<ReactQueryDevtools initialIsOpen={true} />

가장 자주 사용하게되는 옵션은 initialIsOpen 입니다.

true를 주게되면 reactquery 개발자도구가 화면에 표시되게됩니다.

반면 false를 주면 표시되지않습니다.

이러한 개발자도구를 확인할 수 있습니다.

특징적인 부분은 loading, error 상태를 버튼 클릭 한번으로 간단히 트리거할 수 있다는 것입니다.

만들어둔 Providers는 사용을 위해 layout.tsx에 전달해줍니다.

'use client';

import { useQuery } from '@tanstack/react-query';
import { FC } from 'react';

interface TodosProps {}

const Todos: FC<TodosProps> = ({}) => {
  const { isLoading, error, data, isFetching } = useQuery({
    queryKey: ['todos'],
    queryFn: async () => {
      const response = await fetch(
        'https://api.github.com/repos/tannerlinsley/react-query',
      );
      const data = await response.json();
      return data;
    },
  });

  if (isLoading) return <div>로딩중</div>;
  if (error) return <div>에러남</div>;

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{' '}
      <strong>✨ {data.stargazers_count}</strong>{' '}
      <strong>🍴 {data.forks_count}</strong>
      <div>{isFetching ? 'Updating...' : ''}</div>
    </div>
  );
};

export default Todos;

다음은 데이터를 페칭해오는 부분입니다.

리액트쿼리가 제공하는 useQuery함수를 이용해

간단하게 데이터를 가져올 수 있습니다.

이 useQuery함수는 isLoading, error, data 등 다양한 값을 제공해주며

const {
	data,
	dataUpdatedAt,
	error,
	errorUpdateCount,
	errorUpdatedAt,
	failureCount,
	failureReason,
	fetchStatus,
	isError,
	isFetched,
	isFetchedAfterMount,
	isFetching,
	isInitialLoading,
	isLoading,
	isLoadingError,
	isPaused,
	isPlaceholderData,
	isPreviousData,
	isRefetchError,
	isRefetching,
	isStale,
	isSuccess,
	refetch,
	remove,
	status
} = useQuery({
  queryKey,
  queryFn,
  cacheTime,
  enabled,
  networkMode,
  initialData,
  initialDataUpdatedAt,
  keepPreviousData,
  meta,
  notifyOnChangeProps,
  onError,
  onSettled,
  onSuccess,
  placeholderData,
  queryKeyHashFn,
  refetchInterval,
  refetchIntervalInBackground,
  refetchOnMount,
  refetchOnReconnect,
  refetchOnWindowFocus,
  retry,
  retryOnMount,
  retryDelay,
  select,
  staleTime,
  structuralSharing,
  suspense,
  useErrorBoundary,
})

공식문서에 따르면 이렇듯 많은 옵션을 제공해줍니다.

 

이러한 useQuery는

인자로 객체를 전달해주어야 합니다.

queryKey와 queryFn은 필수적으로 전달을 해주어야하며

그 외 다양한 옵션은 해당 링크에서 확인할 수 있습니다.

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

 

useQuery | TanStack Query Docs

const { data,

tanstack.com

 

이때 쿼리키는 배열의 형태로 지정하는 것을 권장합니다.


  const { isLoading, error, data, isFetching } = useQuery({
    queryKey: ['todos'],
    queryFn: async () => {
      const response = await fetch(
        'https://api.github.com/repos/tannerlinsley/react-query',
      );
      const data = await response.json();
      return data;
    },
  });

useQuery를 사용하는 부분만 떼오면 이와 같은 형태가 됩니다.

fetch를 사용하든 axios를 사용하든 그것은 개발자의 자유입니다.

마찬가지로 async를 사용하든 promise구문을 사용하든 그것 역시 자유입니다!


🙄결론

간단하게 데이터를 가져오는 실습을 진행해봤습니다.

RTK Query에 비해 훨씬 hook 스러우며 보일러플레이트가 적고

필요한 타입 설정이 적은 편이라 훨씬 러닝커브가 낮다고 느껴집니다.

반응형