TanStack Query의 생명주기는 데이터가 캐시되고, 사용되고, 갱신되는 과정을 포함합니다. 아래는 주요 상태들에 대한 설명입니다.
상태 | 설명 |
---|---|
fresh | 데이터를 새로 패칭할 필요가 없는 상태입니다. staleTime이 지나지 않은 상태로, 캐시 데이터를 그대로 사용할 수 있습니다. |
stale | 데이터를 새로 패칭해야 하는 상태입니다. staleTime이 지난 후로, 새로운 데이터를 가져오기 위해 쿼리가 실행됩니다. |
active | 현재 컴포넌트에서 사용 중인 쿼리 상태입니다. 컴포넌트가 마운트되어 쿼리를 사용하고 있을 때를 말합니다. |
inactive | 더 이상 사용되지 않는 쿼리 상태입니다. 컴포넌트가 언마운트되거나 쿼리가 더 이상 필요하지 않을 때를 말합니다. |
deleted | 캐시에서 제거된 쿼리 상태입니다. gcTime 이 지나면 쿼리가 캐시에서 삭제되어 이 상태가 됩니다. |
fetching | 데이터를 서버에서 가져오고 있는 상태입니다. 이 상태에서는 isFetching이 true로 설정됩니다. |
기본설정 | 의미 |
---|---|
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)-1. staleTime vs gcTime
staleTime : 얼마의 시간이 흐른 뒤에 stale 취급할 건지 (default: 0)
gcTime : inactive 된 이후로 메모리에 얼마만큼 있을건지 (default: 5분, gcTime 0되면 삭제처리)
(3)-2. staleTime 과 stale/fresh 의 관계
(3)-3. isPending vs. isFetching
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
(데이터를 다시 가져오고 있음)요약
isPending
은 새로운 캐시 데이터를 서버에서 받고 있는지 여부를 나타내며, 캐시 데이터가 있는 경우 false
입니다.isFetching
은 서버에서 데이터를 받고 있는지 여부를 나타내며, 데이터가 로드되는 동안 항상 true
입니다.isPending
은 false
이고 isFetching
은 true
입니다.✔️ useQuery를 할 때, 반드시 알아야 하는 옵션에 대해 살펴봅니다.
(1)-1. 개념
enabled
옵션은 쿼리(queryFn) 실행 여부를 제어합니다. 기본값은 true
(만약 설정하지 않는다면 자동으로 true)이며, false
로 설정하면 쿼리가 자동으로 실행되지 않습니다. 이 옵션을 사용하여 특정 이벤트 발생 시 쿼리를 실행할 수 있습니다.
기본 사용법은 아래와 같아요.
useQuery({
queryKey: ["todos"],
queryFn: getTodos,
enabled: true
})
(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)-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>
}