React Query 시작하기

이재철·2023년 2월 26일
0

react-query

목록 보기
1/12
post-thumbnail

QueryClientProvider

  • QueryClientProvider 컴포넌트로 감싸주고 QueryClient 값을 Props로 주입합니다.
  • 앱 전체에 사용하고자하면 최상위 컴포넌트를 감싸줍니다.
import React from 'react';
import './App.css';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';

const queryClient = new QueryClient();

const App = () => {
  return (
    <QueryClientProvider client={queryClient}>
      <div className="App"></div>
    </QueryClientProvider>
  );
};

export default App;

QueryClient Default Options 적용하기

  • QueryClient에서 모든 query 또는 mutation 기본 옵션을 추가할 수 있습니다.

QueryClient 의 Default Option 적용

QueryClient의 Default Option

import React from 'react';
import './App.css';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      retry: 0,
      suspense: true,
      useErrorBoundary: true
    },
    mutations: {
      retry: 0,
      suspense: true,
      useErrorBoundary: true
    }
  },
})

const App = () => {
  return (
    <QueryClientProvider client={queryClient}>
      <div className="App"></div>
    </QueryClientProvider>
  );
};

export default App;

setQueryDefaults 사용

  • useQuery에서 직접 옵션을 설정하지 않고, 가능한 기본값을 사용하며 재정의 및 특정 쿼리에 대한 변경이 필요한 경우 queryClient.setQueryDefaults 사용
...
// ✅ only todos will retry 2 times
queryClient.setQueryDefaults('getUser', { retry: 2 })
...

useQuery 적용

  • 특정 도메인 페이지에서 필요한 옵션들을 구체적으로 설정
const {data: user, error, status} = useQuery(
  ['getUser'],
  getUserApi,
  {
  	enabled: !!userId,   
    onError: () => {...},
    onSuccess: () => {...}
  }

브라우저에서 사용자가 최신 데이터를 바라봐야 되는 경우

  • 사용자가 해당 화면을 보고 있는 경우
  • 페이지 전환 시
  • 페이지 전환 없이 새로운 데이터 요청 시
refetchOnWindowFocus, // default: true
refetchOnMount, // default: true
refetchOnReconnect, // default: true
  
staleTime // default: 0
cacheTime, // default: 5분 (60*5*1000)

다음과 같은 경우 데이터를 Refetching 자동으로 다시 가져옴

  • refetchOnMount: 쿼리의 새 인스턴스가 마운트 된 경우
  • refetchOnWindowFocus: window가 다시 포커스가 된 경우
  • refetchOnReconnect: 네트워크가 끊어졌다가 다시 연결 된 경우
  • refetchInterval: 쿼리의 refetch interval이 설정된 경우
  • 기본적으로 쿼리 결과는 데이터가 실제로 변경되는지 감지하기 위해 공유함
  • 변경되지 않는 경우 데이터 참조가 변경되지 않는 상태 유지

Default Option

enable

  • useQuery를 동기적으로 사용 가능
  • false로 설정하면 쿼리가 자동으로 호출되지 않음 ➡ 최초 선언 시 호출을 막을수 있음
  • default: true
const {data: user, error, status} = useQuery(
  ['getUser'],
  getUserApi,
  {
  	enabled: !!userId // true가 되면 getUserApi를 실행함
  }

staleTime

  • 쿼리 데이터가 fresh에서 stale로 전환되는데 걸리는 시간
  • Infinity로 설정하면 쿼리 데이터는 직접 캐시를 무효화할 때 까지 fresh상태로 유지
  • 캐시는 메모리에서 관리 ➡ 브라우저 새로고침 후 다시 가져옴
  • default: 0

refetchInterval

  • 일정한 간격으로 refetching이 가능
  • 밀리초로 계속 refetching
  • default: false

refetchIntervalInBackground

  • 탭/창 백그라운드에 있는 동안 쿼리 refetching
  • default: false

refetchOnWindowFocus

  • 윈도우 다시 포커스되었을 때, 데이터 호출 여부
  • default: false

refetchOnReconnect

  • 네트워크가 끊어졌다가 다시 연결된 경우 데이터 호출 여부
  • default: true

refetchOnMount

  • mount 된 경우 reftch 여부 결정합니다.
  • true로 설정한 경우 stale 상태일 때 refetch
  • default: true
  1. parent component render
  2. useQuery 호출 ➡ isFetching, isLoading : true
  3. 요청완료
    • isFetching, isLoading : false
    • query key 값을 식별자 데이터 캐싱처리
    • data fresh상태, staleTime 이후 stale 상태 변환
  4. parent component 리 랜더링되며 자식 children component의 useQuery 호출
    • 데이터 stale상태, refetchOnMount:true 이므로 background refetch가 실행

➡ 처음 fetching 이후 staleTimerefetchOnMount 설정으로 refetching을 하며 총 2번 요청

retryOnMount

  • false로 설정한 경우 쿼리에 오류가 포함되어 mount 시, 쿼리 재시도되지 않습니다.

notifyOnChangeProps

  • 속성이 변경되는 경우만 다시 렌더링 옵션
const {data: user, error, status} = useQuery(
  ['getUser'],
  getUserApi,
  {
  	notifyOnChangeProps: ['data'],
  }
  • const {data: user, error, status} = useQuery(...);data만 변경이 된 경우 리렌더링
    🚫 status를 이용하여 조건부 렌더링을 하는 경우 문제가 발생함 ➡ status 의 변경여부를 감지할 수 없음

tracked

  • 리액트 쿼리는 렌더 중에 사용 중인 속성을 알아서 추적하며, 사용 중인 속성들의 변화가 있는 경우 리렌더링을 함
notifyOnChangeProps: 'tracked'
default 설정이 아닌 경우
  • object rest destructuring을 사용한다면 모든 필드를 추적함으로 주의해야 함🤦
  • 의존성 배열에 사용 중인 속성을 주입하지 않는 다면 정확한 추적이 되지 않음
const userData = useQuery(...);
React.useEffect(() => {
    console.log(userData.data)
})

🚫 tracked를 설정하여 사용 중인 속성은 약간의 오버헤드가 발생할 수 있으므로 상황에 따라 사용해야 함


onSuccess

  • queryFunction 성공적으로 데이터를 가저온 경우 호출되는 함수
  • 쿼리가 성공적으로 새로운 데이터를 가져오거나 setQueryData를 통해 캐시가 업데이트가 될 때마다 실행합니다.

onError

  • queryFunction에서 오류가 발생한 경우 호출되는 함수
  • 쿼리에 오류가 발생하고 오류가 전달되면 콜백 실행

onSettled

  • queryFunction의 성공, 실패 여부와 관계없이 모두 실행되는 함수

useErrorBoundary

  • suspense: true 또는 useErrorBoundary: true 설정한 경우, 모든 오류는 에러바운더리로 넘겨짐
  • default: false

select

  • 쿼리 함수에 반환된 데이터의 일부를 변환하거나 선택
{
 	 select: data => data.filter((user) => user.id === 1));
}

suspense

  • true 설정하면 status === 'loading' 상태인 경우 쿼리 일시 중단
  • true 설정하면 status === 'error' 상태인 경우 런타임 오류 발생
  • default: false

keepPreviousData

  • 새로운 쿼리키 기반으로 데이터를 가져올 때 이전 data를 유지하기 위한 옵션
  • queryKey가 변경되어 새로운 데이터를 요청하는 동안에도 마지막 data의 값을 유지합니다
    • pageNation을 구현할 때, 유용하게 쓰임 ➡ 캐시되지 않는 페이지 호출한 경우 화면의 view 컴포넌트가 사라지는 현상을 방지
    • isPreviusData 값으로 현재 queryKey에 해당하는 값을 확인 할 수 있음

placeholderData

  • 쿼리가 '로드 상태' 데이터에 있으며 initialData가 제공되지 않는 동안 특정 쿼리 관찰자의 자리 표시자로 데이터를 사용

optimisticResults

  • 낙관적으로 설정 ➡ 쿼리가 실제로 가져오기를 시작하기전에 결과를 가져오는 상태

cacheTime

  • default: 5 * 30 * 1000 (5분)
  • unused / inactive 캐시 데이터를 메모리에 유지시킬 시간
  • Infinity 설정 시 쿼리 데이터가 캐시에서 제거되지 않음

retry

  • 요청이 실패한 경우 재요청 실행
  • default: 3

TanStack Query v4 - QueryClientProvider

profile
혼신의 힘을 다하다 🤷‍♂️

0개의 댓글