-
Tanstack-Query (a.k.a React-Query) 입문자들을 위한 간단 설명concept/React, Redux, RN 2024. 4. 14. 19:30
이름 변경
2023년 9월에 React Query는 TanStack Query로 이름이 변경
- React Query는 Facebook에서 유지보수하는 React 공식 라이브러리가 아니라는 점에서 상표권 문제가 있을 수 있었기 때문
- 새로운 이름은 React에 종속되지 않으며, React 외의 다른 프레임워크나 라이브러리와도 함께 사용될 수 있음
TanStack Query 란?
- 공식 문서의 정의에 따르면..
- TanStack Query(FKA React Query)는 종종 웹 애플리케이션용 누락된 데이터 가져오기 라이브러리로 설명되지만 좀 더 기술적인 용어로 말하면 웹 애플리케이션에서 서버 상태 가져오기, 캐싱, 동기화 및 업데이트를 매우 쉽게 만듭니다.
- 웹 앱에서 서버 상태 가져오기, 캐싱, 동기화 및 업데이트를 쉽게 만드는 것
- 전역상태관리와 헷갈리는 사람들이 종종 있는데 엄연히 다르다.
- 전역 상태 관리 도구는 애플리케이션의 상태를 관리하고 여러 컴포넌트 간에 상태를 공유하기 위한 라이브러리. Redux, MobX, Context API 등
- React Query는 데이터 요청 및 캐싱을 관리하기 위한 라이브러리로, API 호출, 데이터 캐싱, 상태 관리 등의 작업을 담당
사용 사례:
- 전역 상태 관리 도구는 주로 애플리케이션의 전역 상태를 관리하고 여러 컴포넌트에서 접근할 수 있어야 할 때 사용. 예를 들어, 로그인 상태, 테마, 언어 설정 등의 전역적인 상태를 관리할 때 유용
- React Query는 주로 데이터 요청과 관련된 작업을 다룰 때 사용됩니다. API 호출, 데이터 캐싱, 새로고침 관리 등을 통해 원격 데이터를 가져와서 애플리케이션에서 사용
TanStack Query 의 장점?
- Caching을 통해 앱의 속도 향상
- 동일한 데이터에 대한 중복 요청을 제거
- 오래된 데이터의 상태를 파악해서 Updating을 지원
- Garbage Collection을 이용해 서버 쪽 데이터 메모리 관리
- React Hooks와 유사한 문법 인터페이스
기본 설치 및 Setting
import { QueryClient, QueryClientProvider } from 'react-query' const queryClient = new QueryClient() function App() { return <QueryClientProvider client={queryClient}> ... //root 컴포넌트 </QueryClientProvider> }
- QueryClient 인스턴스 생성
- 컴포넌트가 QueryClient 인스턴스에 접근할 수 있도록 root가 되는 컴포넌트를 QueryClientProvider로 감싸준다.
- client prop으로 QueryClient를 넘겨준다.
기본 사용 문법
- useQuery (GET)
- v4에서는 useQuery(key, fn, options), useQuery({queryKey, queryFn, ...options}) 두 형태를 모두 지원했는데 이는 유지보수가 힘들고, 매개 변수 타입을 확인하기 위한 런타임 검사도 필요했기 때문에 오로지 객체 형식만 지원하도록 v5에서 변경
const useGetAllFeedbacksBySurveyId = (surveyId: string, options?: UseQueryOptions<Response>) => { return useQuery<Response>({ queryKey: ['feedbacks', surveyId], queryFn: () => get<Response>(`/v1/feedbacks?survey-id=${surveyId}`), ...options, }); }; export default useGetAllFeedbacksBySurveyId; // 이렇게 쿼리를 만들었으면 const { isLoading: isAllDataLoading, data: allData } = useGetAllFeedbacksBySurveyId(surveyId);
- useMutation (POST, UPDATE, DELETE)
const useCreateSurvey = (options?: UseMutationOptions<CreateSurveyResponse, unknown, CreateSurveyRequest>) => { return useMutation<CreateSurveyResponse, unknown, CreateSurveyRequest>({ mutationFn: ({ question_count, question }) => post<CreateSurveyResponse>('/v1/surveys', { question_count, question }), ...options, }); }; export default useCreateSurvey; // 이렇게 뮤테이션을 만들었으면 const { mutate: createSurvey } = useCreateSurvey();
- 캐싱을 어떻게?
- Query Key에 저장하기 때문에 Query key 가 바뀔 때 새롭게 요청함. 그래서 Query Key를 변수로 쓸지 상수로 쓸지 여부를 결정할 수도 있다.
- QueryClient 에 접근해서 데이터를 가져오는 방법
import { useQueryClient } from '@tanstack/react-query'; const queryClient = useQueryClient(); const user = queryClient.getQueryData<{ memberUid: string }>(['user']);
- useQuery Options (각 옵션들의 뜻) 쿼리가 더 중요
- 쿼리 옵션이 더 많다. get 이니까 여러번 안가져 와도 되는 것들은 그렇게 하려고 그럼
- gcTime: Garbage Collection 주기입니다. 데이터 캐시 정리를 얼마나 자주 할 것인지를 설정합니다. 기존엔 cacheTime 이었는데 이름이 바뀜. 쿼리가 사용되고 있는 경우에는 시간을 재지 않다가 쿼리가 사용되지 않는 즉시 시간을 재서 시간이 다 지나면 가비지 컬렉트된다.
- enabled: Query가 활성화되어 있는지 여부를 나타냅니다. 쿼리가 자동으로 실행되지 않도록 할 때 설정 가능. 어떤 시점에 데이터를 불러와야 하는 경우가 있다. 그런데 mutation은 그게 가능한게 query는 그게 안됨. 함수 안에서 호출이 불가하기 때문에!! 함수 안에서 호출하면 hook을 함수 내부에서 호출할 수 없다는 에러가 뜬다. 그런 경우에 이 옵션 사용 가능
- networkMode: 쿼리를 가져오는 방법을 설정합니다. "online" 또는 "offline"가 가능합니다.
- initialData: 초기 데이터입니다. 이것은 쿼리가 처음 만들어질 때 사용됩니다.
- initialDataUpdatedAt: 초기 데이터가 언제 업데이트되었는지를 나타냅니다.
- meta: 쿼리에 대한 메타데이터입니다.
- notifyOnChangeProps: 컴포넌트가 업데이트되는 때를 알려줄 프로퍼티들의 목록입니다. notifyOnChangeProps: ["data"], 이렇게 쓰면 data 값이 변경될 때만 리렌더링이 발생
- placeholderData: 데이터가 로딩 중일 때 보여줄 데이터입니다.
- queryKeyHashFn: 쿼리 키를 해싱하는 함수입니다.
- refetchInterval: 자동으로 쿼리를 다시 실행할 시간 간격입니다. 이 옵션으로 polling을 할 수 있다.
- refetchIntervalInBackground: 백그라운드에서 자동 쿼리 다시 실행이 가능한지 여부를 나타냅니다. 이 옵션으로 polling을 할 수 있다.
- refetchOnMount: 마운트될 때마다 자동으로 쿼리를 다시 실행할지 여부를 나타냅니다.
- refetchOnReconnect: 연결이 재연결될 때마다 자동으로 쿼리를 다시 실행할지 여부를 나타냅니다.
- refetchOnWindowFocus: 창이 포커스될 때마다 자동으로 쿼리를 다시 실행할지 여부를 나타냅니다. 크롬에서 다른 탭을 눌렀다가 다시 원래 탭으로 돌아왔을 때도 이 경우에 해당. 개발자 도구 창에서 focus해 있다가 돌아왔을 때도 해당.
- retry: 실패한 요청을 다시 시도할 횟수입니다. 쿼리를 수동으로 재요청할 때 사용
- retryOnMount: 마운트될 때마다 다시 시도할지 여부를 나타냅니다. 데이터가 stale 상태일 경우, mount 마다 refetch를 실행하는 옵션, always로 값을 주면 마운트할 때 마다 refetch / false 로 주면 최초 fetch 만 하고 refetch 하지 않음. (예를 들어 잘 안바뀌는 데이터를 보여줄 때 사용하면 좋다. 회사 소개 페이지 같은 경우?)
- retryDelay: 다시 시도 간의 지연 시간입니다.
- select: 쿼리의 결과에서 선택하고 반환할 데이터를 지정하는 함수입니다.
- staleTime: 쿼리가 만료되기 전에 캐시된 데이터를 사용할 시간입니다. 데이터가 fresh에서 stale 상태로 변경되는데 걸리는 시간. 만약 staleTime이 3000 이면 fresh 상태에서 3초 뒤에 썩음.
- structuralSharing: 구조 공유 설정입니다.
- throwOnError: 에러가 발생하면 던질지 여부를 나타냅니다.
- useMutation Options
- gcTime: Garbage Collection 주기입니다. 데이터 캐시 정리를 얼마나 자주 할 것인지를 설정합니다.
- mutationKey: 해당 mutation을 식별하는 고유한 키입니다.
- networkMode: 뮤테이션을 보낼 때 사용할 네트워크 모드를 설정합니다. "online" 또는 "offline"가 가능합니다.
- onError: 뮤테이션 실행 중에 에러가 발생했을 때 호출될 콜백 함수입니다.
- onMutate: 뮤테이션을 시작하기 전에 호출될 콜백 함수입니다.
- onSettled: 뮤테이션이 완료된 후 호출될 콜백 함수입니다.
- onSuccess: 뮤테이션 실행에 성공했을 때 호출될 콜백 함수입니다.
- retry: 실패한 요청을 다시 시도할 횟수입니다.
- retryDelay: 다시 시도 간의 지연 시간입니다.
- throwOnError: 에러가 발생하면 던질지 여부를 나타냅니다.
- meta: 뮤테이션에 대한 메타데이터입니다
참고하면 좋은 자료
https://github.com/ssi02014/react-query-tutorial
'concept > React, Redux, RN' 카테고리의 다른 글
Intersection Observer 에서 onIntersect 안에 있는 함수가 useState 상태를 인식하지 못하는 이유와 해결법 (1) 2024.12.26 모던 리액트 딥 다이브 (0) 2024.03.03 [Udemy] 클린코드 리액트 - 소개, State (0) 2024.02.04 채팅 기능 구현을 위한 web socket과 sse 방식 POC (0) 2023.11.06 이미지 최적화를 위한 방법들과 Next/Image (0) 2023.11.05