TanStack-Query 적용

배지호·2024년 1월 5일
0

tanstack-query

목록 보기
1/1
post-thumbnail

아래의 사진은 TanStack Query의 공식 문서 설명이다.

한글 말로 간단하게 정리하면 다음과 같다.

TanStack-Query는 React 에서 서버 상태 가져오기캐싱동기화 및 업데이트를 매우 간편하게 만들어주는 라이브러리이다.

TanStack-Query의 주요 기능

  • 캐싱 및 자동 재요청
  • 클라이언트 데이터와 서버 데이터의 분리
  • 비동기 데이터 처리 간소화

주요 기능들을 하나씩 알아보겠다.

1. 캐싱 및 자동 재요청

TanStack-Query는 API 요청 결과를 캐싱한다.

캐싱이란 데이터나 계산 결과를 임시로 저장하여 나중에 동일한 요청이나 계산이 발생했을 때 더 빠르게 응답하거나 처리하는 기술이다.

TanStack-Query는 미리 캐싱된 데이터를 보여줌으로써 응답 시간이 감소하고 서버 리소스를 절약할 수 있다.

그렇게 되면 새로운 데이터는 언제 바꿔줄건데?

위와 같은 의문점이 생긴다.
결국 캐싱된 데이터를 끝까지 잡고 있다면 사용자는 1년이 지나도 같은 화면을 보게 될 것이다.
그렇다면 데이터 갱신을 react-query가 어떻게 처리하는지 알아보자.

1. 자동 refresh 주기 조절

const { data } = useQuery('exampleQueryKey', fetchData, {
  refetchInterval: 5000, // 5초마다 갱신
});

useQuery 함수의 3번째 인자의 옵션으로 refetchInterval을 설정하면 해당 주기마다 데이터를 자동으로 갱신해준다.

2. 수동 갱신 요청

수동으로 데이터를 갱신하고 싶을 때에 queryClient.invalidQueries 함수를 사용하여 해당 쿼리를 갱신할 수 있다.

3. staleTime과 gcTime

TanStack-Query는 useQuery 함수의 3번째 인자의 옵션으로 staleTime과 gcTime을 설정함으로써 데이터 갱신 관리를 할 수 있다.

staleTime : 데이터가 만료되어도 해당 데이터를 사용하고 UI를 갱신하지 않을 기간을 설정. 만료된 데이터를 사용하는 동안 백그라운드에서는 새로운 데이터를 가져와 갱신

  • staleTime은 캐시된 데이터가 stale 상태로 유지되는 시간을 나타냅니다.
  • 긴 시간으로 설정하면 캐시된 데이터를 오랫동안 사용할 수 있지만, 최신 데이터를 더 오랫동안 반영하지 않을 수 있습니다.
  • 짧게 설정하면 더 빠르게 최신 데이터를 반영하지만, 캐시를 자주 갱신해야 하는 부하가 있을 수 있습니다.

gcTime : 데이터가 캐시에 저장된 상태를 유지하는 기간을 설정.

  • gcTime은 가비지 컬렉션 주기를 나타냅니다.
  • 긴 주기로 설정하면 가비지 컬렉션이 자주 발생하지 않아 애플리케이션 성능에 도움이 될 수 있지만, 캐시된 데이터가 오랫동안 유지될 수 있습니다.
  • 짧게 설정하면 자주 가비지 컬렉션이 발생하여 캐시된 데이터가 빠르게 정리되지만, 이는 성능에 영향을 미칠 수 있습니다.
  • gcTime은 사용하지 않는 데이터를 정리하는 주기를 나타냅니다. 이는 캐시된 데이터가 아닌 사용하지 않는 데이터를 정리하는 역할입니다.

TanStack-Query의 라이프 사이클
1. A 쿼리 mount
2. 데이터 fetching 후 A 쿼리 캐싱
3. 해당 데이터는 fresh 상태에서 staleTime 이후 stale 상태로 변경
4. A 쿼리 unmount
5-1. 캐싱된 데이터는 gcTime 이후 가비지 컬렉션 발생
5-2. 만일 gcTime이 지나기 전에 A 쿼리가 mount 되면, fetch가 실행되고 새로운 값을 가져오는 동안 캐싱된 데이터를 보여줌

const { data } = useQuery('exampleQueryKey', fetchData, {
  staleTime: 10000, // 10초 동안 stale 상태로 유지
  cacheTime: 60000, // 1분 동안 캐시된 데이터 유지
});

2. 클라이언트 데이터와 서버 데이터의 분리

서버 데이터를 클라이언트 데이터와 분리함으로써 전체 애플리케이션의 데이터 관리를 더 효율적으로 구조화, 유지 보수하기 용이하다.

3. 비동기 데이터 처리 간소화

데이터 fetching을 위해 흔히 사용하는 방식 중 하나는 useState와 useEffect를 활용하는 방식이다.

const [questionListData, setQuestionListData] = useState();

const getQuestionListData = async () => {
    const { questions, totalPage } = await getQuestionList({
      page: page,
      title: searchQuery,
    });
    setQuestionListData(questions);
  };

useEffect(() => {
    getQuestionListData();
  }, [searchQuery, page]);

useQuery 함수를 사용하여 불필요한 boilerplate 코드를 줄이고, 코드를 간소화 할 수 있다.

  const getQuestionListData = async () => {
    return await getQuestionList({ page: page, title: searchQuery });
  };

  const { data: questionListData } = useQuery({
    queryKey: ['questionList', searchQuery, page],
    queryFn: getQuestionListData,
    placeholderData: keepPreviousData,
  });

적용 방법

npm i @tanstack/react-query

// app.tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient();

const App = () => {
	return(
		<QueryClientProvider client={queryClient}>
			...
	
		</QueryClientProvider>
	)
};

위와 같이 패키지 설치 후, QueryClientProvider로 전체를 감싸주면 된다.

대표적인 함수

useQuery

데이터를 가져오고 캐시에 저장된 데이터를 반환하거나 새로운 데이터를 요청한다.

Parameter

  • queryKey (배열)

    쿼리를 식별하는 unique한 키값. 이 키는 캐시에 사용된다.

  • queryFn (함수)

    데이터를 가져오는 비동기 함수.

  • options

    쿼리의 추가적인 설정을 담은 객체.

    • retry: 실패한 쿼리를 재시도하는 횟수 설정.
    • enabled: 쿼리를 처음부터 활성화할지 여부 결정.
      기본값은 true이며, false로 설정하면 초기 렌더링 시에 데이터를 요청하지 않음.
    • staleTime: 데이터가 fresh→stale 상태로 변경되는데 걸리는 시간. 데이터가 fetch 되고 나서 staleTime이 지나지 않았다면 unmount 후 mount 되어도 fetch가 일어나지 않는다.
    • gcTime: 쿼리가 캐시에 저장된 데이터를 유지하는 기간
    • refetchOnWindowFocus: 윈도우가 포커스를 얻었을 때 자동으로 데이터를 다시 가져올 지 여부를 지정
    • refetchOnMount: 컴포넌트 마운트가 발생한 경우 데이터를 다시 가져올 지 여부를 지정
    • refetchOnReconnect: 네트워크 재연결이 발생한 경우 데이터를 다시 가져올 지 여부를 지정

useQuery 예시

const fetchDataFunction = async () => {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  return data;
};
  const { data } = useQuery({queryKey: ['myQueryKey'], queryFn: fetchDataFunction);

useMutation

데이터를 업데이트하고, 성공 또는 실패에 따른 상태를 관리한다.

Parameter

  • queryFn

    데이터를 업데이트하는 비동기 함수.

  • options

    쿼리의 추가적인 설정을 담은 객체.

    • retry: mutate 함수 실행 중에 오류가 발생하였을 때 재시도할 횟수 설정.
    • onSuccess: mutation 성공 했을 때 실행하는 콜백 함수
    • onError: mutation 과정에서 오류 발생 했을 때 실행하는 콜백 함수

useMutation 예시

const updateDataFunction = async () => {
  const response = await fetch('https://api.example.com/update', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(newData),
  });
  const updatedData = await response.json();
  return updatedData;
};
const { data, mutate } = useMutation({mutationFn: updateDataFunction});

주의사항

게시글에 정보를 받아오는 queryKey가 questionList인 쿼리가 있다고 가정하자.

예를 들어, 게시글을 작성한 후에는 questionList 쿼리에 대한 데이터가 변경될 것이지만, 기본적으로 React Query는 캐시를 사용하여 데이터를 제공하므로 이전의 데이터가 유지될 수 있습니다. 따라서 해당 쿼리를 무효화하고, 해당 쿼리를 다시 실행하여 새로운 데이터를 가져오게 함으로써 UI를 갱신해야한다.

queryClient.invalidateQueries(['questionList'])

위의 코드를 통해 key값이 questionList인 쿼리를 무효화 할 수 있다.

Reference

Overview | TanStack Query Docs

[React] react-query, 리액트 쿼리를 사용해야 하는 이유

[React-Query] React-Query 개념잡기

[React] TanStack Query v4 (React Query)

TanStack Query v5 정식 버전 살펴보기 (리액트 쿼리)

React Query에서 staleTime과 cacheTime의 차이

profile
파워 벨로거가 될 남자

0개의 댓글