Next.js 14中用TanStack Query实现缓存,避免页面刷新重复请求
解决Next.js 14 + TanStack Query 页面刷新重复请求的方案
1. 配置QueryClient全局缓存规则
在TanStack Query Provider组件中初始化QueryClient时,设置全局默认的缓存参数,让数据在有效期内直接复用缓存,无需重复请求。
示例代码:
// app/providers.tsx import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; const queryClient = new QueryClient({ defaultOptions: { queries: { // 设置数据新鲜期:7天内直接用缓存,不发请求 staleTime: 1000 * 60 * 60 * 24 * 7, // 设置缓存保留时长:30天后才清理缓存数据 cacheTime: 1000 * 60 * 60 * 24 * 30, // 关闭窗口聚焦、页面挂载、网络重连时的自动重取 refetchOnWindowFocus: false, refetchOnMount: false, refetchOnReconnect: false, }, }, }); export function TanStackQueryProvider({ children }: { children: React.ReactNode }) { return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>; }
2. 为单个查询单独配置缓存(可选)
如果全局配置不满足特定请求的需求,可以在useQuery中单独设置缓存规则,优先级高于全局配置:
// app/posts/page.tsx import { useQuery } from '@tanstack/react-query'; import fetchPosts from '@/lib/fetchPosts'; export default function PostsPage() { const { data: posts } = useQuery({ queryKey: ['posts'], queryFn: fetchPosts, // 单独设置该查询的新鲜期为1小时 staleTime: 1000 * 60 * 60, // 缓存保留1天 cacheTime: 1000 * 60 * 60 * 24, refetchOnMount: false, }); if (!posts) return <div>Loading...</div>; return ( <div> {posts.map(post => ( <div key={post.id}>{post.title}</div> ))} </div> ); }
3. 启用本地持久化缓存(进阶)
如果需要页面刷新、甚至关闭浏览器后仍能复用缓存,可以结合本地存储实现缓存持久化:
安装依赖
npm install @tanstack/react-query-persist-client @tanstack/query-sync-storage-persister
修改Provider配置
// app/providers.tsx import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { persistQueryClient } from '@tanstack/react-query-persist-client'; import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'; const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 1000 * 60 * 60 * 24 * 7, cacheTime: 1000 * 60 * 60 * 24 * 30, refetchOnWindowFocus: false, }, }, }); // 用localStorage作为持久化存储 const persister = createSyncStoragePersister({ storage: window.localStorage, }); // 开启缓存持久化,1秒节流更新一次 persistQueryClient({ queryClient, persister, throttleTime: 1000, }); export function TanStackQueryProvider({ children }: { children: React.ReactNode }) { return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>; }
关键参数说明
staleTime:数据被标记为"新鲜"的时长,期间直接返回缓存,不发起请求cacheTime:缓存数据在内存中保留的时长,超时后会被清理- 若需主动更新缓存,可调用
queryClient.invalidateQueries(['posts'])标记缓存为过时,触发重新请求
内容的提问来源于stack exchange,提问作者Kartik Malik
相关产品推荐
相关产品推荐

