01) Tanstack Query life cycle
(1) (캐시 데이터에 대한) LifeCycle 설명
TanStack Query의 생명주기는 데이터가 캐시되고, 사용되고, 갱신되는 과정을 포함합니다.
아래는 주요 상태들에 대한 설명입니다.
상태 | 설명 |
---|---|
fresh | 데이터를 새로 패칭할 필요가 없는 상태입니다. staleTime이 지나지 않은 상태로, 캐시 데이터를 그대로 사용할 수 있습니다. |
stale | 데이터를 새로 패칭해야 하는 상태입니다. staleTime이 지난 후로, 새로운 데이터를 가져오기 위해 쿼리가 실행됩니다. |
active | 현재 컴포넌트에서 사용 중인 쿼리 상태입니다. 컴포넌트가 마운트되어 쿼리를 사용하고 있을 때를 말합니다. |
inactive | 더 이상 사용되지 않는 쿼리 상태입니다. 컴포넌트가 언마운트되거나 쿼리가 더 이상 필요하지 않을 때를 말합니다. |
deleted | 캐시에서 제거된 쿼리 상태입니다. gcTime 이 지나면 쿼리가 캐시에서 삭제되어 이 상태가 됩니다. |
fetching | 데이터를 서버에서 가져오고 있는 상태입니다. 이 상태에서는 isFetching이 true로 설정됩니다. |
(2) default config(기본 설정)
기본 설정 | 의미 |
staleTime: 0 | useQuery 또는 useInfiniteQuery에 등록된 queryFn 을 통해 fetch 받아온 데이터는 항상 stale data 취급 |
refetchOnMount: true | useQuery 또는 useInfiniteQuery 가 있는 컴포넌트가 마운트 시 stale data 를 refetch 자동 실행 |
refetchOnWindowFocus: true | 실행중인 브라우저 화면을 focus 할 때 마다 stale data를 refetch 자동 실행 |
refetchOnReconnect: true | Network 가 끊겼다가 재연결 되었을 때 stale data를 refetch 자동 실행 |
gcTime(cacheTime): 5분 (1000 x 60 x 5 ms) | useQuery 또는 useInfiniteQuery가 있는 컴포넌트가 언마운트 되었을 때 inactive query라 부르며, inactive 상태가 5분 경과 후 GC(가비지콜렉터)에 의해 cache data 삭제 처리 |
retry: 3 | useQuery 또는 useInfiniteQuery에 등록된 queryFn 이 API 서버에 요청을 보내서 실패하더라도 바로 에러를 띄우지 않고 총 3번까지 재요청을 자동으로 시도 |
useQuery 는 캐시데이터에 기반하여 동작합니다. 컴포넌트가 새로 마운트되어도 캐시 데이터가 fresh 하다면 fetch 하지 않습니다!
(3) 헷갈리는 개념 정리
- (3)-1. staleTime vs gcTime
- staleTime
- : 얼마의 시간이 흐른 뒤에 stale 취급할 건지 (default: 0)
- gcTime
- : inactive 된 이후로 메모리에 얼마만큼 있을건지 (default: 5분, gcTime 0되면 삭제처리)
- (3)-2. staleTime 과 stale/fresh 의 관계
- staleTime > 0 이면, fresh data
- staleTime = 0 이면, stale data
- (3)-3. isPending vs. isFetching
isPending
vsisFetching
Tanstack Query
에서 isPending
과 isFetching
의 차이를 이해하는 것은 중요한데, 특히 캐시된 데이터와 새로운 데이터를 구별하는 데 도움이 됩니다.
isPending
:- 새로운 캐시 데이터를 서버에서 받고 있는 지 여부를 나타냅니다.
- 기존의 캐시된 데이터가 있는 경우,
isPending
은false
이고,isFetching
은true
입니다. - 캐시된 데이터가 없고 새로 데이터를 가져오는 경우,
isPending
은true
가 됩니다.
isFetching
:- 서버에서 데이터를 받고 있는지 여부를 나타냅니다.
- 서버에서 데이터를 가져오는 중일 때 항상
true
입니다.
시나리오 설명
- 메인 페이지에서 데이터 로드 (첫 번째 마운트):
useQuery
가 처음 실행되고 서버에서 데이터를 가져옵니다.isPending
:true
(새로운 캐시 데이터를 서버에서 받고 있는 중)isFetching
:true
(서버에서 데이터를 받고 있는 중)
- 상세 페이지로 이동:
- 메인 페이지가 언마운트되고, 상세 페이지가 마운트됩니다.
- 만약 상세 페이지에서도
useQuery("todos", getTodos)
를 사용하고 있다면:- 이미 캐시된 데이터가 있기 때문에, 상세 페이지의
isPending
은false
이고isFetching
은true
입니다.
- 이미 캐시된 데이터가 있기 때문에, 상세 페이지의
- 메인 페이지로 돌아옴 (두 번째 마운트):
- 메인 페이지가 다시 마운트됩니다.
- 캐시된 데이터가 있는 상태로 마운트되므로:
isPending
:false
(캐시된 데이터가 있기 때문에 새로운 데이터를 기다리지 않음)isFetching
:true
(데이터를 다시 가져오고 있음)
예시 코드
// src > pages > Main.jsx
import { useQuery } from "@tanstack/react-query";
import getTodos from "@/api/getTodos";
function Main() {
const { isPending, isFetching } = useQuery({
queryKey: ["todos"],
queryFn: getTodos
});
console.log("isPending: ", isPending);
console.log("isFetching: ", isFetching);
return (
<div>
<h1>Main Page</h1>
</div>
);
}
export default Main;
콘솔 로그 예상 값
- 첫 번째 메인 페이지 마운트:
isPending
:true
isFetching
:true
- 상세 페이지 이동 후 다시 메인 페이지로 돌아옴:
isPending
:false
isFetching
:true
요약
isPending
은 새로운 캐시 데이터를 서버에서 받고 있는지 여부를 나타내며, 캐시 데이터가 있는 경우false
입니다.isFetching
은 서버에서 데이터를 받고 있는지 여부를 나타내며, 데이터가 로드되는 동안 항상true
입니다.- 캐시된 데이터가 있는 경우, 페이지가 다시 마운트될 때
isPending
은false
이고isFetching
은true
입니다.
02) Must-know options
(1) enabled
- (1)-1. 개념기본 사용법은 아래와 같아요.
useQuery({ queryKey: ["todos"], queryFn: getTodos, enabled: true })
enabled
옵션은 쿼리(queryFn) 실행 여부를 제어합니다. 기본값은true
(만약 설정하지 않는다면 자동으로 true)이며,false
로 설정하면 쿼리가 자동으로 실행되지 않습니다. 이 옵션을 사용하여 특정 이벤트 발생 시 쿼리를 실행할 수 있습니다.- (1)-2. 사용 예제
- (1)-2-1. Disabling/Pausing Queries (이벤트 발생 시에만 수동 실행하고 싶을 때)
const { data, refetch } = useQuery({
queryKey: ["todos"],
queryFn: getTodos,
enabled: false
});
return (
<div>
<button onClick={() => refetch()}>데이터 불러오기</button>
</div>
);
- (1)-2-2. Dependent Queries(useQuery 2개 이상이며 실행순서 설정 필요할 때)
// Dependent Query 예제 (순차적 query 실행)
// Get the user
const { data: user } = useQuery({
queryKey: ['user', email],
queryFn: getUserByEmail,
})
const userId = user?.id
// Then get the user's projects
const { status, fetchStatus, data: projects, } = useQuery({
queryKey: ['projects', userId],
queryFn: getProjectsByUser,
// 쿼리는 userId가 존재하는 경우에만 실행돼요 :)
enabled: !!userId
})
// 여기서 !!userId 는 Boolean(userId)와 같습니다.
(2) select
- (2)-1. 개념
select
옵션은 쿼리 함수에서 반환된 데이터를 변형하여 사용할 수 있도록 합니다. 데이터의 특정 부분만 선택하거나, 데이터를 변환하여 사용할 때 유용해요. 단, 캐시 데이터는 원본 데이터를 유지합니다.- (2)-2. 사용예제
import { useQuery } from 'react-query'
function User() {
const { data } = useQuery({
queryKey: ["user"],
queryFn: fetchUser,
select: user => user.username
});
return <div>Username: {data}</div>
}
'library' 카테고리의 다른 글
[240617 TIL] Optimistic Update with Tanstack Query (1) | 2024.06.17 |
---|---|
[240615 WIL] queryKey (0) | 2024.06.15 |
[240613 TIL] Auth with Tanstack Query (0) | 2024.06.13 |
[240605 TIL] Tanstack Query - 2 (0) | 2024.06.05 |
[240604 TIL] clsx (0) | 2024.06.04 |