2222
2323## 주요 컨셉 및 가이드 목차
2424
25- - [ 📃 React Query 개요 및 기능] ( #📃-react-query-개요-및-기능 )
26- - [ 개요] ( #개요 )
27- - [ 기능] ( #기능 )
28- - [ React Query 기본 설정] ( #react-query-기본-설정 )
29- - [ Devtools] ( #devtools )
30- - [ options] ( #options )
31- - [ v4] ( #v4 )
32- - [ 캐싱 라이프 사이클] ( #캐싱-라이프-사이클 )
33- - [ useQuery] ( #usequery )
34- - [ useQuery 기본 문법] ( #usequery-기본-문법 )
35- - [ useQuery 주요 리턴 데이터] ( #usequery-주요-리턴-데이터 )
36- - [ v4부터는 status의 idle 상태값이 제거되고 fetchStatus가 추가] ( #v4부터는-status의-idle-상태값이-제거되고-fetchstatus가-추가 )
37- - [ v4부터는 왜 status, fetchStatus 나눠서 다루는 걸까?] ( #v4부터는-왜-status-fetchstatus-나눠서-다루는-걸까 )
38- - [ cacheTime과 staleTime중 어떤 값을 더 크게 해야할까?] ( #cachetime과-staletime-중-어떤-값을-더-크게-해야할까 )
39- - [ useQuery 주요 옵션] ( #usequery-주요-옵션 )
40- - [ staleTime과 cacheTime] ( #staletime과-cachetime )
41- - [ refetchOnMount] ( #refetchonmount )
42- - [ refetchOnWindowFocus] ( #refetchonwindowfocus )
43- - [ Polling] ( #polling )
44- - [ enabled refetch] ( #enabled-refetch )
45- - [ retry] ( #retry )
46- - [ select] ( #select )
47- - [ keepPreviousData] ( #keeppreviousdata )
48- - [ placeholderData] ( #placeholderdata )
49- - [ Parallel] ( #parallel )
50- - [ Dependent Queries] ( #dependent-queries )
51- - [ useQueryClient] ( #usequeryclient )
52- - [ Initial Query Data] ( #initial-query-data )
53- - [ Prefetching] ( #prefetching )
54- - [ Infinite Queries] ( #infinite-queries )
55- - [ useMutation] ( #usemutation )
56- - [ mutate와 mutateAsync는 무엇을 사용하는게 좋을까?] ( #mutate와-mutateasync는-무엇을-사용하는게-좋을까 )
57- - [ cancelQueries] ( #cancelqueries )
58- - [ 쿼리 무효화] ( #쿼리-무효화 )
59- - [ 캐시 데이터 즉시 업데이트] ( #캐시-데이터-즉시-업데이트 )
60- - [ Optimistic Update] ( #optimistic-update )
61- - [ useQueryErrorResetBoundary] ( #usequeryerrorresetboundary )
62- - [ Suspense] ( #suspense )
63- - [ Default Query Function] ( #default-query-function )
64- - [ React Query Typescript] ( #react-query-typescript )
65- - [ useQuery] ( #usequery-1 )
66- - [ useMutation] ( #usemutation-1 )
25+ 1 . [ React Query 개요 및 기능] ( #개요 )
26+ 2 . [ 기본 설정(QueryClientProvider, QueryClient)] ( #react-query-기본-설정 )
27+ 3 . [ React Query Devtools] ( #devtools )
28+ 4 . [ React Query 캐싱 라이프 사이클] ( #캐싱-라이프-사이클 )
29+ 5 . [ useQuery] ( #usequery )
30+ 6 . [ useQuery 주요 리턴 데이터] ( #usequery-주요-리턴-데이터 )
31+ 7 . [ staleTime과 cacheTime] ( #staletime과-cachetime )
32+ 8 . [ 마운트 될 때마다 재요청하는 refetchOnMount] ( #refetchonmount )
33+ 9 . [ 윈도우가 포커싱 될 때마다 재요청하는 refetchOnWindowFocus] ( #refetchonwindowfocus )
34+ 10 . [ Polling 방식을 구현하기 위한 refetchInterval와 refetchIntervalInBackground)] ( #polling )
35+ 11 . [ 자동 실행의 enabled와 수동으로 쿼리를 다시 요청하는 refetch] ( #enabled-refetch )
36+ 12 . [ 실패한 쿼리에 대해 재요청하는 retry] ( #retry )
37+ 13 . [ onSuccess, onError, onSettled] ( #onsuccess-onerror-onsettled )
38+ 14 . [ select를 이용한 데이터 변환] ( #select )
39+ 15 . [ Paginated 구현에 유용한 keepPreviousData] ( #keeppreviousdata )
40+ 16 . [ 쿼리를 병렬(Parallel) 요청할 수 있는 useQueries] ( #parallel )
41+ 17 . [ 종속 쿼리(Dependent Queries)] ( #dependent-queries )
42+ 18 . [ QueryClient 인스턴스를 반환하는 useQueryClient] ( #usequeryclient )
43+ 19 . [ 초기 데이터를 설정할 수 있는 initialData] ( #initial-query-data )
44+ 20 . [ 데이터를 미리 불러오는 PreFetching] ( #prefetching )
45+ 21 . [ Infinite Queries(무한 쿼리) + useInfiniteQuery] ( #infinite-queries )
46+ 22 . [ 서버와 HTTP CUD관련 작업을 위한 useMutation] ( #usemutation )
47+ 23 . [ 쿼리 수동 무효화 cancelQueries] ( #cancelqueries )
48+ 24 . [ 쿼리를 무효화할 수 있는 queryClient.invalidateQueries] ( #쿼리-무효화 )
49+ 25 . [ 캐시 데이터 즉시 업데이트를 위한 queryClient.setQueryData] ( #캐시-데이터-즉시-업데이트 )
50+ 26 . [ 사용자 경험(UX)을 올려주는 Optimistic Updates(낙관적 업데이트)] ( #optimistic-update )
51+ 27 . [ 에러가 발생했을 때 Fallback UI를 선언적으로 보여주기 위한 ErrorBoundary + useQueryErrorResetBoundary] ( #usequeryerrorresetboundary )
52+ 28 . [ 서버 로딩중일 때 Fallback UI를 선언적으로 보여주기 위한 Suspense] ( #suspense )
53+ 29 . [ 앱 전체에 동일한 쿼리 함수를 공유하는 Default Query Function] ( #default-query-function )
54+ 30 . [ 리액트 쿼리에 타입스크립트 적용] ( #react-query-typescript )
6755
6856<br />
6957
@@ -175,8 +163,6 @@ import { ReactQueryDevtools } from "react-query/devtools";
175163
176164### options
177165
178- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
179-
180166- initialIsOpen (Boolean)
181167 - ` true ` 이면 개발 도구가 기본적으로 열려 있도록 설정할 수 있다.
182168- position?: ("top-left" | "top-right" | "bottom-left" | "bottom-right")
@@ -188,8 +174,6 @@ import { ReactQueryDevtools } from "react-query/devtools";
188174
189175### v4
190176
191- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
192-
193177- v4부터는 devtools를 위한 별도의 패키지 설치가 필요하다.
194178
195179``` bash
@@ -243,8 +227,6 @@ function App() {
243227
244228### useQuery 기본 문법
245229
246- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
247-
248230- [ useQuery v4] ( https://tanstack.com/query/v4/docs/react/reference/useQuery )
249231
250232``` jsx
@@ -346,8 +328,6 @@ const useSuperHeroData = (heroId: string) => {
346328
347329### useQuery 주요 리턴 데이터
348330
349- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
350-
351331``` js
352332const { status , isLoading , isError , error , data , isFetching , ... } = useQuery (
353333 [" colors" , pageNum],
@@ -374,8 +354,6 @@ const { status, isLoading, isError, error, data, isFetching, ... } = useQuery(
374354
375355### v4부터는 status의 idle 상태값이 제거되고 fetchStatus가 추가
376356
377- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
378-
379357- TanStack Query(v4) 부터는 status의 ` idle이 제거 ` 되고, 새로운 상태값인 ` fetchStatus ` 가 추가됐다.
380358- fetchStatus
381359 - fetching: 쿼리가 현재 실행중이다.
@@ -386,8 +364,6 @@ const { status, isLoading, isError, error, data, isFetching, ... } = useQuery(
386364
387365### v4부터는 왜 status, fetchStatus 나눠서 다루는 걸까?
388366
389- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
390-
391367- fetchStatus는 HTTP 네트워크 연결 상태와 좀 더 관련된 상태 데이터이다.
392368 - 예를 들어, status가 ` success ` 상태라면 주로 fetchStatus는 ` idle ` 상태지만, 백그라운드에서 re-fetch가 발생할 때 ` fetching ` 상태일 수 있다.
393369 - status가 보통 ` loading ` 상태일 때 fetchStatus는 주로 ` fetching ` 를 갖지만, 네트워크 연결이 되어 있지 않은 경우 ` paused ` 상태를 가질 수 있다.
@@ -400,20 +376,6 @@ const { status, isLoading, isError, error, data, isFetching, ... } = useQuery(
400376
401377<br />
402378
403- ### cacheTime과 staleTime 중 어떤 값을 더 크게 해야할까?
404-
405- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
406-
407- - ` cacheTime ` 의 기본값은 ` 300000ms ` , 즉 5분이다.
408- - ` staleTime ` 의 기본값은 ` 0ms ` , 즉 0초이며, 이는 한번 fetch 된 데이터는 기본적으로 곧바로 ` stale ` 상태가 되는 것을 의미한다.
409- - 만약 ` staleTime ` 이 ` cacheTime ` 보다 큰 값을 가지게 되면 어떻게 될까? 예를 들어, ` staleTime ` 이 ` 10분 ` , ` cacheTime ` 이 ` 5분 ` 이라고 가정해보자.
410- - ` staleTime ` 에 의해 데이터는 ` 10분 ` 동안 ` fresh ` 한 상태로 간주된다. 그러다 ` 10분 ` 이 지나게 되면 ` stale ` 한 상태가 되며, 그 즉시 query는 백그라운드에서 refetching을 시도한다.
411- - 그런데, ` cacheTime ` 은 ` 5분 ` 으로 설정이 돼 있다. 즉, 이미 ` 5분 ` 이 지난 시점에 query의 ` key ` 에 해당하는 데이터는 삭제되었고, Garbage Collector에 의해 메모리의 할당이 해제된 상태이다. 따라서 query는 다시 네트워크를 통해 데이터를 fetch해야 한다.
412- - 만약 ` cacheTime ` 이 ` staleTime ` 보다 더 큰 값을 가지게 되면 어떻게 될까? ` staleTime ` 이 지나 데이터가 ` stale ` 상태가 되면, 아직 유효한 cache로부터 데이터를 가져오면 되기 때문에, 네트워크 요청이 필요하지 않게 되며, cache의 기능을 제대로 활용한 동작이 된다.
413- - 즉, ` cacheTime ` 의 값을 ` staleTime ` 의 값보다 크게 설정하는 것이 바람직하다고 할 수 있다.
414-
415- <br />
416-
417379## useQuery 주요 옵션
418380
419381[ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
@@ -422,8 +384,6 @@ const { status, isLoading, isError, error, data, isFetching, ... } = useQuery(
422384
423385### staleTime과 cacheTime
424386
425- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
426-
427387- stale은 용어 뜻대로 ` 썩은 ` 이라는 의미이다. 즉, 최신 상태가 아니라는 의미이다.
428388- fresh는 뜻 그대로 ` 신선한 ` 이라는 의미이다. 즉, 최신 상태라는 의미이다.
429389
@@ -460,8 +420,6 @@ const { isLoading, isFetching, data, isError, error } = useQuery(
460420
461421### refetchOnMount
462422
463- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
464-
465423``` jsx
466424const { isLoading , isFetching , data , isError , error } = useQuery (
467425 [" super-hero" ],
@@ -481,8 +439,6 @@ const { isLoading, isFetching, data, isError, error } = useQuery(
481439
482440### refetchOnWindowFocus
483441
484- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
485-
486442``` jsx
487443const { isLoading , isFetching , data , isError , error } = useQuery (
488444 [" super-hero" ],
@@ -501,8 +457,6 @@ const { isLoading, isFetching, data, isError, error } = useQuery(
501457
502458### Polling
503459
504- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
505-
506460``` jsx
507461const { isLoading , isFetching , data , isError , error } = useQuery (
508462 [" super-hero" ],
@@ -523,8 +477,6 @@ const { isLoading, isFetching, data, isError, error } = useQuery(
523477
524478### enabled refetch
525479
526- [ 목차 이동] ( #주요-컨셉-및-가이드-목차 )
527-
528480``` jsx
529481const { isLoading , isFetching , data , isError , error , refetch } = useQuery (
530482 [" super-hero" ],
@@ -557,8 +509,6 @@ return (
557509
558510### retry
559511
560- [목차 이동](#주요-컨셉-및-가이드-목차)
561-
562512` ` ` jsx
563513const result = useQuery ([" todos" , 1 ], fetchTodoListPage, {
564514 retry: 10 , // 오류를 표시하기 전에 실패한 요청을 10번 재시도합니다.
@@ -573,9 +523,41 @@ const result = useQuery(["todos", 1], fetchTodoListPage, {
573523
574524<br />
575525
576- ### select
526+ ### onSuccess, onError, onSettled
577527
578- [목차 이동](#주요-컨셉-및-가이드-목차)
528+ _NOTE_: 위 Callback은 ` useQuery` 옵션에서 [` @Deprecated` 되어 삭제될 예정](https://github.com/TanStack/query/pull/5353)(v5에 반영)이다. 단, ` useMutation` 에서는 사용 가능하다.
529+
530+ ` ` ` jsx
531+ const onSuccess = useCallback ((data ) => {
532+ console .log (" Success" , data);
533+ }, []);
534+
535+ const onError = useCallback ((err ) => {
536+ console .log (" Error" , err);
537+ }, []);
538+
539+ const onSettled = useCallback (() => {
540+ console .log (" Settled" );
541+ }, []);
542+
543+ const { isLoading , isFetching , data , isError , error , refetch } = useQuery (
544+ [" super-hero" ],
545+ getSuperHero,
546+ {
547+ onSuccess,
548+ onError,
549+ onSettled,
550+ }
551+ );
552+ ` ` `
553+
554+ - ` onSuccess` 함수는 쿼리 요청이 성공적으로 진행돼서 새 데이터를 가져오거나 캐시가 업데이트될 때마다 실행된다.
555+ - ` onError` 함수는 쿼리에 오류가 발생하고 오류가 전달되면 실행된다.
556+ - ` onSettled` 함수는 쿼리 요청이 성공, 실패 모두 실행된다.
557+
558+ <br />
559+
560+ ### select
579561
580562` ` ` jsx
581563const { isLoading , isFetching , data , isError , error , refetch } = useQuery (
@@ -607,8 +589,6 @@ return (
607589
608590### keepPreviousData
609591
610- [목차 이동](#주요-컨셉-및-가이드-목차)
611-
612592` ` ` jsx
613593const fetchColors = async (pageNum : number ) => {
614594 return await axios .get (
@@ -630,8 +610,6 @@ const { isLoading, isError, error, data, isFetching, isPreviousData } =
630610
631611### placeholderData
632612
633- [목차 이동](#주요-컨셉-및-가이드-목차)
634-
635613` ` ` js
636614function Todos () {
637615 const placeholderData = useMemo (() => generateFakeTodos (), []);
@@ -990,8 +968,6 @@ try {
990968
991969### mutate와 mutateAsync는 무엇을 사용하는게 좋을까?
992970
993- [목차 이동](#주요-컨셉-및-가이드-목차)
994-
995971- 대부분의 경우 우리는 mutate를 사용하는 것이 유리하다. 왜냐하면 mutate는 콜백(onSuccess, onError)를 통해 data와 error에 접근할 수 있기 때문에 우리가 특별히 핸들링 해 줄 필요가 없다.
996972- 하지만 mutateAsync는 Promise를 직접 다루기 때문에 이런 에러 핸들링 같은 부분을 직접 다뤄야한다.
997973 - 만약 이를 다루지 않으면 ` unhandled promise rejection` 에러가 발생 할 수 있다.
@@ -1055,9 +1031,9 @@ const useAddSuperHeroData = () => {
10551031
10561032- 만약 무효화 하려는 키가 여러 개라면 아래 예제와 같이 다음과 같이 배열로 보내주면 된다.
10571033
1058- ` ` ` tsx
1059- queryClient .invalidateQueries ([" super-heroes" , " posts" , " comment" ]);
1060- ` ` `
1034+ ` ` ` tsx
1035+ queryClient .invalidateQueries ([" super-heroes" , " posts" , " comment" ]);
1036+ ` ` `
10611037
10621038- 위에 ` enabled/ refetch` 에서도 언급했지만 ` enabled: false ` 옵션을 주면` queryClient` 가 쿼리를 다시 가져오는 방법 중 ` invalidateQueries` 와 ` refetchQueries` 를 무시한다.
10631039 - [Disabling/Pausing Queries](https://tanstack.com/query/v4/docs/guides/disabling-queries?from=reactQueryV3&original=https://react-query-v3.tanstack.com/guides/disabling-queries) 참고
@@ -1158,13 +1134,13 @@ const useAddSuperHeroData = () => {
11581134
11591135- ` useQueryErrorResetBoundary` 는 ` ErrorBoundary` 와 함께 사용되는데 이는, 기본적으로 리액트 공식문서에서 기본 코드 베이스가 제공되긴 하지만 좀 더 쉽게 활용할 수 있는 ` react- error- boundary` 라이브러리가 존재하고, react-query 공식문서에서도 해당 라이브러리 사용을 예시로 제공해주기 때문에 ` react- error- boundary` 를 설치해서 사용해보자.
11601136
1161- ` ` ` bash
1162- $ npm i react- error- boundary
1163- # or
1164- $ pnpm add react- error- boundary
1165- # or
1166- $ yarn add react- error- boundary
1167- ` ` `
1137+ ` ` ` bash
1138+ $ npm i react- error- boundary
1139+ # or
1140+ $ pnpm add react- error- boundary
1141+ # or
1142+ $ yarn add react- error- boundary
1143+ ` ` `
11681144
11691145- 설치 후에 아래와 같은 QueryErrorBoundary라는 컴포넌트를 생성하고, 그 내부에 ` useQueryErrorResetBoundary` 훅을 호출해 ` reset` 함수를 가져온다.
11701146- 아래 코드 내용은 단순하다.
@@ -1332,8 +1308,6 @@ const useSuperHeroData = (heroId: string) => {
13321308
13331309### useQuery
13341310
1335- [목차 이동](#주요-컨셉-및-가이드-목차)
1336-
13371311현재 useQuery가 갖고 있는 제네릭은 ` 4 개` 이며, 다음과 같다.
13381312
133913131. TQueryFnData: useQuery로 실행하는 query function의 ` 실행 결과` 의 타입을 지정하는 제네릭 타입이다.
@@ -1374,9 +1348,8 @@ const { data } = useQuery<
13741348
13751349### useMutation
13761350
1377- [목차 이동](#주요-컨셉-및-가이드-목차)
1378-
13791351useMutation도 useQuery와 동일하게 현재 4개이며, 다음과 같다.
1352+
138013531. TData: useMutaion에 넘겨준 mutation function의 `실행 결과`의 타입을 지정하는 제네릭 타입이다.
13811354 - data의 타입과 onSuccess(1번째 인자)의 인자의 타입으로 활용된다.
138213552. TError: useMutaion에 넘겨준 mutation function의 `error` 형식을 정하는 제네릭 타입이다.
0 commit comments