React Query

Jung taeWoong·2022년 2월 14일
0

React-Query

목록 보기
1/1
post-thumbnail

React Query

  • 서버의 데이터를 가져오고(fetching), 저장하고(caching), UI와 동기화(synchronizing), 최신 데이터로 update하는 로직을 쉽게 작성할수 있도록 도와주는 라이브러리
  • 서버 데이터를 캐싱하여 저장하고 항상 최신 데이터 상태를 유지시킨다.
$ npm i react-query
// or
$ yarn add react-query
import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';

const queryClient = new QueryClient();

const App = () => {
  return (
    <QueryCLientProvider client={queryCLient}>
      ...
    </QueryClientProvider>
    )
}

useQuery

  • GET 요청에서 사용

Key

  • key는 string 또는 array 타입으로 해당 쿼리를 식별할 수 있는 값으로 사용된다
  • 같은 key면 같은 데이터를 불러오게된다. A, B 컴포넌트에서 같은 key값을 사용한다면 먼저 렌더링 되는 곳 예를 들어 A에서 api 호출을 하게되면 B에서는 A에서 받아온 값을 사용하게됨 (각각 api 호출 ❌)
  • key를 array 타입으로 사용하는 경우 배열 아이템의 순서가 달라져도 다른 key로 간주한다.

key를 Array 형태로 사용하는 경우
1. 데이터 항목을 식별하기 위한 값을 넣는 경우
2. 매개변수가 있는 쿼리

  • === 쿼리에 종속성을 추가하기 위해 사용
import { useQuery } from 'react-query';

const Awesome = () => {
  const { data } = useQuery('key', fetcher);
}

useQuery 속성

  • useQuery의 반환값으로 데이터 사용에 필요한 쿼리에 모든 정보가 포함되어있음
const {
  data,
  dataUpdatedAt,
  error,
  errorUpdatedAt,
  failureCount,
  isError,
  isFetched,
  isFetchedAfterMount,
  isFetching,
  isIdle,
  isLoading,
  isLoadingError,
  isPlaceholderData,
  isPreviousData,
  isRefetchError,
  isState,
  isSuccess,
  refetch,
  remove,
  status,
} useQuery(key, fetcher, {
   cacheTime,
   enabled,
   initialData,
   initialDataUpdatedAt
   isDataEqual,
   keepPreviousData,
   meta,
   notifyOnChangeProps,
   notifyOnChangePropsExclusions,
   onError,
   onSettled,
   onSuccess,
   placeholderData,
   queryKeyHashFn,
   refetchInterval,
   refetchIntervalInBackground,
   refetchOnMount,
   refetchOnReconnect,
   refetchOnWindowFocus,
   retry,
   retryOnMount,
   retryDelay,
   select,
   staleTime,
   structuralSharing,
   suspense,
   useErrorBoundary,
}
  • isFetching: 비동기 요청이 아직 resolve 되지 않았음을 의미
  • isLoading: isFetching의 하위 집합, 비동기 요청이 fetching 상태에 있다는 의미(+캐시된 데이터도 없음)
  • isSuccess: 쿼리가 데이터를 성공적으로 받아왔고 사용할 수 있는 상태
  • data: 쿼리가 성공하고 반환된 데이터
  • isError: query를 실패하면 default option으로 3번 재요청을 하게 되는데 결과적으로 요청이 실패된 상태
  • error: throw된 실제 오류에 대한 정보
  • isIdel: 쿼리가 enable: false로 설정되고 초기 데이터를 사용할 수 없는 경우

isFetching vs isLoading

  • isFetching은 캐시데이터가 있든 없든 데이터를 load 중일때 true

Dev Tools

  • 공식문서
  • useQuery의 디버깅을 도와주는 툴
    • key 값으로 쿼리를 표시
    • 모든 쿼리의 상태를 알려준다. (active, inactive, stale, ...)
    • 쿼리가 마지막으로 업데이트된 타임스탬프를 제공
    • 쿼리가 반환한 데이터를 확인 가능
  • 추가적인 패키지 라이브러리 설치 없이 react-query 패키지의 번들로 제공
  • 기본적으로 process.env.NODE_ENV === 'development가 설정되있다.
 import { ReactQueryDevtools } from 'react-query/devtools'

Stale Data

  • 오래된 데이터라는 의미
  • staleTime: 쿼리 데이터를 refetching하는지 여부를 결정하는 시간
  • staleTime의 default 값이 0sec인 이유: react query 창시자의 트윗 멘션
  • 기본적으로 cache data를 오래된 데이터로 간주
  • stale data가 자동으로 refetching 하는 경우
    • 쿼리의 새 인스턴스가 마운트 되었을 때
    • 브라우저 창이 refocuse될 때
    • 네트워크가 재연결 될 때
    • 쿼리 옵션으로 refetch interval 설정이 되있을 때

cacheTime

  • 데이터를 나중에 재사용하기 위해 캐시하게 되는데 그 캐시데이터의 만료시간 default(5min)
  • 사용된 쿼리가 마지막으로 active 되고서 경과한 시간
  • 만료시간이 지나면 garbage collection이 자동으로 수거

prefetching

  • 데이터를 미리 가져와 캐싱하는 기법
  • 사용자가 해당 페이지 진입시 다음 특정 데이터가 필요한 페이지를 방문할 가능성이 높을때 사용
  • 사용자가 미래에 원할것이라 생각하는 모든 데이터에 사용할 수 있다.(페이지네이션 등)
  • queryClient의 메소드인 prefetchQuery 사용
import { useEffect } from 'react';
import { useQuery, useQueryClient } from 'react-query';

const Example = () => {
  const queryclient = useQueryClient();
  
  const { data, isLoading } = useQuery(queryKey, queryFn, {
      stealeTime: 2000, // 2sec 후 오래된 데이터로 간주 
      keepPreviousData: true,  // 쿼리 키가 변경되어 새 데이터를 가져올 때 이전 데이터가 유지됨
    });
  
  useEffect(() => {
    queryClient.prefetchQuery(queryKey, queryFn);
  }, [dependency])
}

export default Example;

mutation

  • 서버의 데이터를 수정하는 경우 사용 (POST)
  • useQuery와 비슷하지만 mutation func을 반환한다.
  • 데이터를 저장하지 않기 때문에 query key가 필요없다.
  • isLoading but no isFetching
  • useQuery와 달리 실패시 재 요청을 하지 않는다.(설정으로 변경 가능)
  • useMutation 인자로 queryFnc를 전달하여 mutation 객체로 사용
  • mutationmutate 속성을 통해 등록한 queryFnc를 호출시킨다.

mutation lifecylce

  • mutationObj.isError: mutation에 등록한 함수가 실패했을 때
  • mutationObj.isLoading: mutation에 등록한 함수가 로딩중일 때
  • mutationObj.isSuccess: mutation에 등록한 함수가 성공했을 때
import { useMutation } from 'react-query';

const Example = () => {
  
  const exampleMutation = useMutation((param) => examplePostAPI(param));
  
  return (
    <>
      <button 
      	type="button" 
      	onClick={() => exampleMutation.mutate(param)}
      	>
      	Click
    	</button>
      {exampleMutation.isError && (<span>Error</span>)}
      {exampleMutation.isLoading && (<span>Loading</span>)}
      {exampleMutation.isSuccess && (<span>Success</span>)}
    </>
  )
}

export default Example;

useInfiniteQuery

  • useQuery와 반환되는 데이터 속성이 다르다.

select

profile
Front-End 😲

0개의 댓글