React Query 알고쓰기

홍창현·2025년 3월 26일
post-thumbnail

React Query는 데이터를 페치할때 가장 많이 쓰는 라이브러리입니다. 하지만, 굳이 React Query가 없어도 데이터를 페치할 수 있는데 왜 이 라이브러리를 사용할까요?

분명 사용하는 이유는 있을 겁니다. 이번 포스팅에서 React Query가 왜 유용한지 확인해보고 주요 메서드에 대해 소개하겠습니다.


React Query를 사용하는 이유

서버 상태 관리

React Query는 주로 서버 상태를 관리할 때 사용합니다. 서버 상태란 API를 통해 가져오는 데이터로, 애플리케이션 외부에 존재하며 지속적인 동기화가 필요한 데이터를 말합니다.

자동 데이터 동기화

서버 데이터와 로컬 상태를 명확히 구분하여 관리할 수 있어 상태 관리의 복잡성을 줄일 수 있습니다. 또한, 여러 컴포넌트에서 동일한 데이터를 사용할 때도 React Query가 자동으로 데이터를 동기화하여 일관성을 유지합니다.

서버 상태는 React Query가 관리하고, 로컬 상태는 상태관리 라이브러리로 관리한다고 볼 수 있습니다.

캐싱 및 성능 최적화

React Query는 자동으로 데이터를 캐싱하여, 불필요한 네트워크 요청을 방지합니다.

staleTimegcTime(cacheTime) 설정을 통해, 데이터의 유효 기간을 관리하고, 적절한 시점에 서버에서 최신 데이터를 가져올 수 있습니다.

staleTimegcTime은 어떤 역할을 하고 있고, 어떻게 작동하는지 정확히 알 필요가 있습니다.

  • staleTime : 데이터가 오래된 상태가 되기까지의 시간입니다. 즉, 데이터가 신선하다고 판단되는 시간입니다.
  • gcTime : 데이터를 얼마동안 캐싱할지 시간입니다.

staleTime이 10초, gcTime이 100초인 경우에 데이터를 페치하는 상황

만약 이러한 상황에서 데이터를 어떻게 처리할까요?

  • 초기에 데이터를 받아온후 10초 내로 다시 데이터를 받게되면, 캐싱된 데이터를 가져오게 됩니다. 이때 staleTime은 초기화되지 않습니다.
  • staleTime을 넘긴 30초정도에 데이터를 받게되면,
    • 첫 번째로, 캐싱된 데이터를 가져오게 됩니다.
    • 두 번째로, staleTime을 넘겨 더이상 신선한 데이터가 아니므로 백그라운드에서 신선한 데이터를 요청합니다.
    • 세 번째로, 받아온 데이터를 렌더링합니다. 이 과정에서 staleTimegcTime은 다시 초기화됩니다.
  • gcTime을 넘긴 시간에 데이터를 받게되면, 캐싱된 데이터가 없으므로 새로 데이터를 받아오고 렌더링합니다.

이 외에도 많은 기능들

  • 비동기 상태(로딩, 에러, 성공) 관리 편리
  • Optimistic Update(낙관적 업데이트)
  • 페이징, 무한스크롤

React Query를 사용하면 위와 같은 기능들을 사용할 수 있다. 물론, React Query없이도 이를 직접 구현하여 만들 수도 있지만 제공해주는 기능이기에 정말 편리한 라이브러리이다.

본질은 서버 상태를 관리하는 것이다.


React Query의 대표 메서드

제 기준으로 React Query에서 많이 사용했던 메서드를 소개하려 합니다. 적어도, 제가 사용한 메서드는 다 알아야하니 제가 사용한 것 위주로 정리하겠습니다.

  • useQuery, useSuspenseQuery, useMutation

useQuery

데이터를 가져올 때(GET) 사용합니다.

export const useCheckLiveExist = ({ liveId }: { liveId: string }) => {
  return useQuery<LiveExistenceResponse, Error>({
    queryKey: ['checkLiveExist'],
    queryFn: () => checkLiveExist({ liveId }),
    refetchOnWindowFocus: false,
    initialData: { existed: true }
  });
};

initialData와 같은 속성들을 사용할 수 있으며, staleTime이나 cacheTime속성도 추가할 수 있습니다.

useSuspenseQuery

export const useMainLive = () => {
  return useSuspenseQuery<MainLive[], Error>({
    queryKey: ['mainLive'],
    queryFn: fetchMainLive,
    refetchOnWindowFocus: false
  });
};

<Suspense fallback={<RecommendLiveSkeleton />}>
    <RecommendLive />
</Suspense>

쓰는 방법은 useQuery와 같습니다. 하지만, 중요한 것은 여기서 받아온 데이터는 React의 Suspense와 함께 활용해주어야 합니다.

위의 코드에서 RecommendLiveuseMainLive를 호출한 컴포넌트입니다.

useMutation

데이터를 변경할 때 사용합니다. GET메서드를 제외한 POST, PUT, PATCH, DELETE에 사용할 수 있습니다.

export default function useFetchStreamKey({ onSuccess, onError }: Params = {}): UseMutationResult<
  StreamKeyResponse,
  Error,
  string
> {
  return useMutation({
    mutationFn: fetchStreamKey,
    onSuccess,
    onError
  });
}

이번 포스팅으로 React Query를 왜 사용하는지 제 기준으로 정리를 해보았습니다.

profile
원리를 이해하는 프론트엔드 개발자입니다

0개의 댓글