[Tanstack Query] 8. 쿼리 캐시와 데이터 프리페칭

임승민·2025년 2월 16일
0

Tanstack Query

목록 보기
8/9
post-thumbnail

1. 쿼리 캐시

쿼리 캐시는 이전에 가져온 데이터를 저장하여, 동일한 요청이 발생할 때 네트워크 요청 없이 빠르게 반환할 수 있도록 하는 기능이다.

TanStack Query는 기본적으로 쿼리 키를 기준으로 데이터를 캐싱한다.

특징

1. staleTime (신선도 시간)

이 시간이 지나기 전까지는 캐시된 데이터를 신선한(fresh) 상태로 간주한다.

stale상태는 새로운 데이터를 가져와도 되는 상태로 이때 리패치가 발생하면 새로 요청한다.

별다른 설정을 하지 않았다면 컴포넌트 마운트, 윈도우 포커스, 네트워크 재연결 등 발생하면 자동 리패치가 일어난다.

  • 기본값: 0ms (즉시 stale 상태가 됨)

2. gcTime (가비지 컬렉션 시간)

캐시 데이터가 메모리에서 삭제되기까지의 시간이다.

  • 기본값: 5분

3. 캐시된 데이터를 바로 반환

쿼리 요청 시 캐시 데이터가 있다면 바로 반환을 한다.

staleTime이 지나지 않았다면 추가 요청 없이 그대로 사용한다.

4. 쿼리 키가 동일하면 캐시 공유

동일한 쿼리 키를 가진 useQuery들은 같은 캐시 데이터를 참조한다.

2. queryClient

쿼리 캐시는 queryClient로 관리할 수 있고, useQueryClient()로 접근 가능하다.

기본적으로 특정 쿼리 키의 캐시 데이터 가져오기, 삭제, 갱신이 가능하다.

import { useQueryClient } from '@tanstack/vue-query'
const queryClient = useQueryClient()

// 캐시 데이터 가져오기
const userCache = queryClient.getQueryData(['user', userId])
// 캐시 삭제
queryClient.removeQueries(['user', userId])
// 데이터 강제 갱신 (리페치)
queryClient.invalidateQueries(['user', userId])

추가 메서드 소개

메서드설명
getQueryData(queryKey)특정 queryKey에 해당하는 캐시된 데이터 가져오기
setQueryData(queryKey, data)특정 queryKey의 캐시 데이터를 강제로 설정
invalidateQueries(queryKey?)특정 queryKey(또는 전체)의 캐시를 무효화하고 다시 요청
removeQueries(queryKey?)특정 queryKey(또는 전체)의 캐시 데이터를 삭제
fetchQuery(queryKey, queryFn)특정 쿼리를 실행하고 결과를 캐시에 저장 (프리페칭)
prefetchQuery(queryKey, queryFn)특정 쿼리를 미리 프리페칭 하지만, 기존 캐시가 유효하면 요청 안 함
cancelQueries(queryKey?)특정 queryKey의 요청을 취소
refetchQueries(queryKey?)특정 queryKey의 데이터를 다시 불러오기
getQueryState(queryKey)특정 queryKey의 상태(stale, fetching, inactive 등) 조회

자세한 사용법은 아래 주소에 있다.

https://tanstack.com/query/v5/docs/reference/QueryClient

3.  데이터 프리패칭

프리패칭이란 사용자가 요청하기 전에 미리 데이터를 가져와서, 요청 시 더 빠르게 응답하는 기법이다.

prefetchQueryprefetchInfiniteQuery를 활용해서 미리 데이터를 가져올 수 있다.

queryClient.prefetchQuery: 특정 queryKey의 데이터를 미리 가져오고, useQuery가 실행될 때 캐시에서 즉시 반환한다.

queryClient.prefetchInfiniteQuery: useInfiniteQuery에 사용할 데이터를 미리 가져온다.

useQuery + staleTime: staleTime이 0이면 프리패칭을 해도 상세페이지로 가면 다시 새 데이터를 요청을 한다. 적절한 staleTime 설정을 해야 프리패칭 효과를 얻을 수 있다.

  • useQuery의 staleTime이 5초라면 프리패칭 후 5초 동안 fresh상태다. 그래서 5초 전에 해당 쿼리가 있는 페이지로 이동하면 프리패칭된 데이터를 사용한다. 하지만 5초후에 이동하면 새 데이터를 요청한다.

프리패칭

<!-- 사용자 목록 페이지 -->
<script setup>
import { useQueryClient } from '@tanstack/vue-query'
const queryClient = useQueryClient()

const prefetchUserDetail = (userId) => {
	queryClient.prefetchQuery({
    queryKey: ['user', userId],
    queryFn: () => fetchUser(userId),
    gcTime: 1000 * 60 * 1
  })
}
</script>
<template>
  <ul>
    <li v-for="user in users" :key="user.id">
      <!-- 마우스를 올리면 프리패칭 실행 -->
      <router-link to="`/user/${user.id}`"
        @mouseenter="prefetchUserDetail(user.id)"
      >
        {{ user.name }} 상세보기
      </router-link>
    </li>
  </ul>
</template>

프리패칭 데이터 사용

<!-- 사용자 상세보기 페이지 -->
<script setup>
import { useRoute } from 'vue-router'
import { useQuery } from '@tanstack/vue-query'
const route = useRoute()
const userId = route.params.id

const { data: user } = useQuery({
    queryKey: ['user', userId],
    queryFn: () => fetchUser(userId),
    staleTime: 5000
  })
</script>
<template>
  <div>
    <h2>{{ user.name }}의 상세 정보</h2>
    <p>이메일: {{ user.email }}</p>
    <p>나이: {{ user.age }}</p>
  </div>
</template>

결과 예상

  1. 목록 페이지에서 링크에 마우스를 올리면 프리패칭 된다.
  2. 사용자 상세 페이지로 이동하면 useQuery가 실행된다.
  3. 데이터 요청 없이 프리패칭한 데이터를 사용한다.

0개의 댓글

관련 채용 정보