Tạo QueryClient BÊN NGOÀI component; dùng cache() factory trong Next.js App Router để mỗi request server có instance riêng — tránh data leak giữa users.
- QueryClient là singleton quản lý toàn bộ cache và config.
- Tạo BÊN NGOÀI component để tránh re-create mỗi render. defaultOptions áp dụng cho tất cả queries/mutations trừ khi override per-query:
new QueryClient({ defaultOptions: { queries: { staleTime: 60_000, gcTime: 5 60_000, retry: 2, retryDelay: (attempt) => Math.min(1000 2 ** attempt, 30_000), refetchOnWindowFocus: false } } }). - Retry strategy: mặc định retry 3 lần với exponential backoff, có thể set
retry: (count, error) => error.status !== 404 && count < 3để không retry 404. - Error handling defaults: từ v5 không còn
onErrorglobal — dùngQueryCachelistener:new QueryClient({ queryCache: new QueryCache({ onError: (error) => toast.error(error.message) }) }). staleTime strategy theo loại data: static data (currencies, countries) →Infinity, user data → 5 phút, real-time data → 0. - Trong Next.js App Router, tạo QueryClient trong server component và dùng
makeQueryClient()factory pattern để mỗi request có instance riêng tránh data leaking giữa users.
Create QueryClient OUTSIDE the component; use a cache() factory in Next.js App Router so each server request has its own instance — prevents data leaking between users.
- QueryClient is a singleton managing the entire cache and config.
- Create it OUTSIDE any component to avoid re-creating it on every render. defaultOptions apply to all queries/mutations unless overridden per-query:
new QueryClient({ defaultOptions: { queries: { staleTime: 60_000, gcTime: 5 60_000, retry: 2, retryDelay: (attempt) => Math.min(1000 2 ** attempt, 30_000), refetchOnWindowFocus: false } } }). - Retry strategy: default 3 retries with exponential backoff; can be customized:
retry: (count, error) => error.status !== 404 && count < 3to skip retrying 404s. - Error handling from v5: global
onErroris no longer available — use aQueryCachelistener:new QueryClient({ queryCache: new QueryCache({ onError: (error) => toast.error(error.message) }) }). staleTime strategy by data type: static data (currencies, countries) →Infinity, user data → 5 minutes, real-time data → 0. - In Next.js App Router, create QueryClient in a server component and use a
makeQueryClient()factory with React'scache()so each request gets its own instance, preventing data leaking between users.