본문 바로가기
Frontend/React Query

useQuery

by 잘먹는 개발자 에단 2024. 12. 13.

React Query의 useQuery는 React 어플리케이션에서 데이터를 관리하고 서버와의 통신을 효율적으로 처리할 수 있도록 도와주는 훅입니다.

 

useQuery는 데이터를 가져오는 과정과 상태관리를 간소화하며, 캐싱, 리패칭, 로딩/에러 상태 관리 등을 자동으로 처리해줍니다.

 

useQuery(queryKey, fetchFunction, options);

 

첫번째 매개변수로 쿼리키 query key 

- 데이터를 구분하기 위한 키입니다.

- 배열로 작성됩니다.

- 예를 들어, ['posts'] 

 

두번째로 데이터를 가져오는 함수 fetch function

- 데이터를 가져오는 비동기 함수입니다.

 

세번째로 옵션 객체 option object 를 받을 수 있습니다.

 

 

 

옵션들을 보겠습니다.

 

1. enabled

- 기본값 true

- 쿼리의 자동 실행 여부를 제어합니다.

- false로 설정하면 특정 조건에서만 데이터를 가져오도록 할 수 있습니다. 

- false로 설정하고 refetch로 원하는 시점에만 데이터를 가져올 수도 있습니다.

const { data } = useQuery(['posts'], fetchPosts, { enabled: false });
// 필요할 때 실행
if (shouldFetch) refetch();

 

2. staleTime

- 기본값 0 : 즉시 오래된 상태로 간주합니다.

- 데이터를 오래된 (stale)한 상태로 간주하기까지의 시간을 밀리초 단위로 설정합니다.

- 데이터가 stale 하지 않으면 재요청하지 않고, 캐시 데이터를 그대로 사용합니다.

const { data } = useQuery(['posts'], fetchPosts, { staleTime: 5000 });

 

3. cacheTime

- 기본값 5분 (300,000ms) 

- 데이터를 캐시에 유지하는 시간을 밀리초 단위로 설정합니다.

    ㄴ 이 시간이 지나면 데이터가 캐시에서 삭제됩니다.

- staleTime과 차이점

    ㄴ staleTime : 데이터가 오래된 상태인지 여부

    ㄴ cacheTime : 데이터가 캐시에 남아있는 시간

- 아래의 경우, 데이터는 10초동안 캐시에 유지되며 이후 삭제됩니다.

const { data } = useQuery(['posts'], fetchPosts, { cacheTime: 10000 });

 

4. refetchOnWindowFocus

- 기본값 true

- 브라우저 창이 다시 활성화될 때 데이터를 자동으로 가져옵니다.

- 아래의 경우 브라우저 창이 다시 활성화될 때 데이터를 자동으로 가져오지 않습니다.

const { data } = useQuery(['posts'], fetchPosts, { refetchOnWindowFocus: false });

 

 

 

5. refetchInterval

- 기본값 false (자동갱신 비활성화)

- 데이터를 주기적으로 가져오고 싶을 때 사용합니다. 밀리초 단위로 설정합니다.

- 아래의 경우 데이터를 5초마다 새로 가져옵니다.

const { data } = useQuery(['posts'], fetchPosts, { refetchInterval: 5000 });

 

6. onSuccess, onError ( Deprecated 되었습니다 ) 

- 데이터 요청이 성공/실패했을 때 실행할 콜백함수입니다.

 

이 옵션은 v5에서 Deprecated 되었습니다.

Deprecated 된 이유는 

1. 추가 렌더링이 생긴다.

2. 캐시를 사용할 경우에 콜백이 실행되지 않을 가능성이 있다. 

 

그렇다면 onSuccess가 꼭 필요한 경우는 어떻게 해야할까?

useEffect를 useQuery가 반환하는 객체의 data에 걸자. 

 

onError 같은 경우는 root의 queryClient에서 사용하라고 합니다. 

const queryClient = new QueryClient({
  queryCache: new QueryCache({
    onError: (error) =>
      toast.error(`Something went wrong: ${error.message}`),
  }),
})

 

api마다 에러메시지를 던지고 싶다면

const queryClient = new QueryClient({
  queryCache: new QueryCache({
    onError: (error, query) => {
      if (query.meta.errorMessage) {
        toast.error(query.meta.errorMessage)
      }
    },
  }),
})

export function useTodos() {
  return useQuery({
    queryKey: ['todos', 'list'],
    queryFn: fetchTodos,
    meta: {
      errorMessage: 'Failed to fetch todos',
    },
  })
}

 

 

7. retry

- 기본값 3 (3번 재시도)

- 요청이 실패했을 때 몇 번 재시도할 지 설정합니다.

    - false로 설정하면 재시도 하지 않습니다.

 

8. retryDelay

- 기본값 : (attempt) => Math.min(100*2**attempt, 30000)

- 재시도 간격을 설정합니다. 기본적으로 지수 함수로 증가합니다.

 

9. initialData

- 기본값 : 없음

- 쿼리가 완료되기 전에 기본값으로 사용할 초기 데이터를 설정합니다.

const { data } = useQuery(['posts'], fetchPosts, {
  initialData: [{ id: 1, title: 'Initial Post' }],
});

 

 

 

참고한 post

react-query v5에 useQuery의 onSuccess가 사라졌다.

 

react-query v5에 useQuery의 onSuccess가 사라졌다.

사이드프로젝트하다가 api에 문제가 생겨서 손보던 중 react-query v5가 나온걸 보고 v5로 업데이트 했다. 인터페이스가 좀 바뀌어서 이것저것 고치는데 onSuccess를 넣을 자리가 안보였다. 검색해보니

wnsdufdl.tistory.com

 

'Frontend > React Query' 카테고리의 다른 글

Suspense, ErrorBoundary 그리고 React Query  (1) 2024.12.12