Next.js服务端组件中Apollo Client设置no-cache仍缓存问题排查
解决方案
核心原因
Next.js服务端组件中,全局单例的Apollo Client实例会跨请求复用缓存,no-cache策略在服务端场景下无法完全规避缓存复用——它只会跳过读取缓存,但仍会写入缓存,且后续请求会复用同一个缓存实例。
修复步骤
1. 改为请求级创建Apollo Client实例
避免全局单例,为每个请求创建独立的客户端实例,确保缓存不跨请求共享:
修改lib/apollo-client.ts为工厂函数:
import { ApolloClient, InMemoryCache } from "@apollo/client"; export const createApolloClient = () => new ApolloClient({ uri: process.env.NEXT_PUBLIC_GRAPHQL_URI || 'http://localhost:3000/api/graphql', cache: new InMemoryCache(), connectToDevTools: process.browser, // 仅在客户端开启DevTools defaultOptions: { query: { fetchPolicy: 'no-cache', errorPolicy: 'all', }, } });
在page.tsx中创建实例:
// 替换原import语句 import { createApolloClient } from "@/lib/apollo-client"; async function fetchData() { const events: EventProps[] = []; const newEvents: EventProps[] = []; try { // 为当前请求创建新客户端 const client = createApolloClient(); const { data } = await client.query({ query: EVENT_QUERY, fetchPolicy: 'network-only', // 替换为更严格的策略 }); events.push(...data.events); } catch (error) { console.error('Error fetching events from GraphQL:', error); } // ...其余代码不变 }
2. 使用network-only替代no-cache
Apollo Client中:
no-cache:请求网络,但会将结果写入缓存network-only:强制请求网络,不读取缓存,也不写入缓存
完全符合“不使用缓存”的需求,替换查询的fetchPolicy即可。
3. 禁用Next.js页面静态缓存(可选)
如果页面开启了静态生成(SSG)或增量静态再生(ISR),Next.js自身会缓存页面内容。添加revalidate: 0强制每次请求重新生成页面:
export const revalidate = 0; export default async function EventsPage() { // ...页面代码不变 }
验证方式
- 检查GraphQL服务器日志,确认每次页面请求都触发新查询
- 在浏览器Network标签中查看GraphQL响应是否为最新数据
- 排查是否有CDN、反向代理等中间层缓存了请求结果
内容的提问来源于stack exchange,提问作者James Nganga
相关产品推荐
相关产品推荐

