우선 React Query의 라이프 사이클을 보자
React Query 라이프 사이클
React Query는 5단계로 라이프 사이클이 구성되어 있다.
서버에서 데이터를 받는 사이 데이터를 추가, 수정, 삭제등으로 인한 최신화가 필요한 상태
컴포넌트가 마운트, 업데이트되면 다시 데이터를 요청
Fresh 상태에서 Stale 상태로 변경되는데 걸리는 시간이 StaleTime
일정 시간이 지나면 가비지 콜렉터가 캐시에서 제거
기본값은 5분
Inactive 상태에서 캐싱된 상태로 남아있는 시간이 cacheTime
결국 React Query의 캐싱은 staleTime과 cacheTime을 통해 이루어진다.
staleTime과 cacheTime
말 그대로 " 신선하지 않은 " 을 뜻한다.
캐싱된 데이터는 stale 상태.
신선하다는 것 = 서버에서 조회한 데이터는 요청한 당시의 snapshot.
외부 요청으로 데이터가 변경된 경우, 기존 데이터는 오래된 데이터 -> stale 상태
stale 상태 = 최신화가 필요. -> refetch 상황에 refetch가 발생
데이터가 fresh 상태에서 stale 상태로 변경되는데 걸리는 시간. default 값은 0
fresh 상태일때는 페이지를 이동했다가 돌아왔을 경우에도 fetch가 일어나지 않는다.
즉, 데이터가 한번 fetch 되고 staleTIme이 지나지 않았다면 unmount 후 mount가 발생해도 다시 fetch가 발생하지 않는다.
default 값이 0 -> 즉시 stale하다고 판단. 캐싱 데이터와는 무관하게 계속 fetching
(캐싱 데이터를 사용하고 싶어도 기본값이 0이기 때문에 캐싱 데이터를 사용할 수 없음)
staleTime을 지정하지 않고 사용한다면 React Query의 캐싱 기능을 활용할 수 없다.
자주 변경되는 데이터라면 지정하지 않는 편이 좋지만, 정적인 데이터 또는 자주 변경될 필요가 없는 데이터라면 staleTime을 지정해서 서버의 부담을 줄여주는 것이 좋다.
전역으로 StaleTime을 설정
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000, // 1초 (1000 = 1초)
},
},
});
특정 쿼리에만 staleTime 설정
const user = useQuery("post", getPost, {
staleTime: 1000, // 1초 (1000 = 1초)
});
데이터가 inactive(사용하지 않는) 상태일 때 캐싱된 상태로 남아있는 시간
쿼리 인스턴스가 unmount -> 데이터는 inactive 상태 -> 캐시는 cacheTime 만큼 유지
쿼리 인스턴스가 다시 마운트되면 데이터를 fatch하는 동안 cacheTime이 지나지 않은 캐시 데이터를 보여준다.
cacheTime이 지나면 가비지 콜렉터로 삭제
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 20000, // 20초 (1000 = 1초)
cacheTime: 30000, // 30초 (1000 = 1초)
},
},
});
staleTime처럼 cacheTime을 사용해서 옵션을 지정 가능
개별 Query에 cacheTime을 설정 가능
staleTime이 cacheTime보다 길더라도 cacheTime이 지나면 데이터가 사라지기 때문에 적용할 때 staleTime보다 cacheTime이 더 길어야 한다.
default 값은 staleTime은 0, cacheTime은 5분
useQuery 최초 마운트 시, useQuery가 useEffect마냥 처음에 무조건 실행할 것인지를 설정하는 옵션
해당 useQuery가 fetcher 함수를 호출하고, 실패했을 때 retry를 실행한다.
처음에는 useQuery가 필요없고 특정 작업을 한 뒤에 useQuery가 필요한 경우,
enabled 옵션을 설정이 없다면 retry로 인해서 서버에 불필요한 요청을 보내게 된다.
이런 경우 useQuery의 enabled 옵션을 통해 막아줄 수 있다.
const user = useQuery("post", getPost, {
staleTime: 1000,
enabled: input, // false = don't retry, true = retry.
});
enabled 옵션은 false인 경우 retry를 발생시키지 않는다.
그리고 다시 fetching이 필요한 경우 조건을 통해서 위와같이 enabled 옵션을 true로 바꿔주면 다시 데이터를 받아온다.
queries에 staleTime과 cacheTime 외에도
default : true
데이터가 stale 상태일 경우 윈도우 포커싱이 될 때 refetch 실행 옵션을 정할 수 있다.
default : true
데이터가 stale 상태일 경우 마운트 마다 refetch 실행 옵션을 정할 수 있다.
default : true
데이터가 stale 상태일 경우 재 연결될 때마다 refetch 실행 옵션을 정할 수 있다.
default : 3
실패한 쿼리를 재시도하는 횟수를 정하는 옵션
만약 true로 설정 시 무한 재시도를 하고, false일 경우 재시도를 하지 않는다.
만약 Post라는 컴포넌트가 postDataQuery 리턴 중 0번 인덱스에 있는 데이터만을 사용하는 컴포넌트라면, useQuery의 옵션중 select라는 옵션을 사용하면 비교적 간단하게 처리 할 수 있다.
function PostList () {
const { data } = postDataQuery(
{
select: (data) => data[0]
}
)
return <Post data={data} />;
}
select옵션은 함수를 인자로 받는데, 파라미터로 queryFunction의 리턴값을 전달해주고, 함수의 리턴값을 data로 전달한다.
물론 아래처럼 데이터 변형도 가능하다.
{
select: data => data.reverse()
}