- 현우
","language":"javascript"},"rv":2,"parentBlockId":"_root_","sortKey":".o0rr","rt":3},"01kg540zmsr0gcvgqtpwzyshsf":{"id":"01kg540zmsr0gcvgqtpwzyshsf","type":"image","version":3,"value":{"image":{"id":"4dre2n","imageKey":"image/slashpagePost/20260129/235525_BLDRy2deRS3yNrllmh","path":"https://upload.cafenono.com/image/slashpagePost/20260129/235525_BLDRy2deRS3yNrllmh?q=80&s=1280x180&t=outside&f=webp","originalImageSize":{"width":1773,"height":368},"dominantColor":"#25242b","isAnimated":false,"mimeType":"image/png","originalContentLength":35435,"updatedAt":"2026-01-29T14:55:26.000Z","createdAt":"2026-01-29T14:55:25.000Z","domain":{"id":"d3mqew"},"previewHash":"U24_trxvs.t7.Af6RiR%%OfQRiR%-=ogWAWB","page":{"id":"1q3vdn2pxr5x42xy49pr"},"hasTransparentPixels":false,"filename":"image-2026-1-29_18-14-13.png"},"extra":{"isRepresentative":true},"shapeConfigurable":true},"rv":4,"parentBlockId":"_root_","sortKey":".o0u","rt":1},"01kg540zmv1dwdt5w6w35fdd86":{"id":"01kg540zmv1dwdt5w6w35fdd86","type":"text","version":1,"value":{"tokens":[{"text":"데이터를 정상적으로 저장했다면, 데이터 로드는 아래와 같이 컴포저블의 일부 함수를 호출해 바로 불러와줄 수 있다."}]},"rv":3,"parentBlockId":"_root_","sortKey":".o0v","rt":1},"01kg541bgdv9662d2fs2q32n5p":{"id":"01kg541bgdv9662d2fs2q32n5p","type":"code","version":1,"value":{"code":"// Form.vue (로드)\n\n
// 브라우저 새로고침 전, 내부적으로 이런 형태로 캐싱 처리를 진행한다.
QueryCache: Map {
"['todo']" => Query { data: [...], dataUpdateAt: 1234567890 }
}
// 하지만 인메모리 캐시를 사용하면서 새로고침 시에 런타임이 초기화되고, 모든 캐시는 손실된다.
QueryCache: Map {} // (비어있음)// 1. 쿼리 생성 시
const query = queryCache.build(client, {
queryKey: ['todos'],
queryFn: fetchTodos
});
// 2. TanStack Query가 내부적으로 queryFn을 실행
const result = await query.options.queryFn();
// 3. 데이터 저장
query.state = {
data: result,
dataUpdatedAt: Date.now();
status: 'success'
}
// 4. staleTime 경과 확인
const isStale = Date.now() - query.state.dataUpdatedAt > query.options.staleTime
// 5. gcTime 경과 시에 제거
if (query.observers.length === 0) {
setTimeout(() => {
queryCache.remove(query);
}, query.options.gcTime)
}QueryClient
└─ QueryCache (Map)
├─ Query['todos']
│ ├─ state: { data, dataUpdatedAt, status }
│ ├─ observers: [Observer1, Observer2]
│ └─ options: { staleTime, gcTime }
│
└─ Query['user', 1]
├─ state: { data, dataUpdatedAt, status }
├─ observers: []
└─ options: { staleTime, gcTime }import { QueryClient, VueQueryPlugin } from '@tanstack/vue-query';
import { persistQueryClient } from '@tanstack/query-persist-client-core';
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';
// main.js
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 30 // 30sec
gcTime: 1000 * 60 // 60sec
}
}
});
persistQueryClient({
queryClient,
persister: createSyncStoragePersister({ storage: window.localStorage }),
});
...
app.use(VueQueryPlugin, { queryClient });