You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js结合RTK Query无法重置缓存,求技术解决方案

解决Next.js + RTK Query服务端API调用缓存问题

问题背景

使用Next.js结合next-redux-wrapper和RTK Query在服务端发起外部API调用时,遇到API响应被缓存的问题,已尝试添加revalidate、配置fetchBaseQuery的cache: 'no-store'和next: { revalidate: 5 },均无效。当前实现代码:

CompaniesPage.getInitialProps = initialPagePropsWithCompanies;

// ---
import { createWrapper } from 'next-redux-wrapper';

const wrapper = createWrapper<ReturnType<typeof makeStore>>(makeStore);
export const initialPagePropsWithCompanies = wrapper.getInitialPageProps((store: AppStore) => async () => {
  store.dispatch(api.endpoints.getHomePage.initiate());
  await Promise.all(store.dispatch(api.util.getRunningQueriesThunk()));
  return { props: {} };
});

解决方案

1. 强制RTK Query刷新请求

RTK Query自身会缓存查询结果,即使Next.js不缓存,也可能返回旧数据。发起请求时添加forceRefetch: true强制刷新:

store.dispatch(api.endpoints.getHomePage.initiate(undefined, { forceRefetch: true }));

或者在API切片的endpoint定义中直接禁用RTK Query缓存:

endpoints: (builder) => ({
  getHomePage: builder.query({
    query: () => '/home',
    cacheTime: 0, // 立即清理缓存
    staleTime: 0, // 数据立即过期
  }),
})

2. 彻底禁用Next.js服务端fetch缓存

在fetchBaseQuery配置中同时设置cache: 'no-store'和next: { revalidate: 0 },确保Next.js不对该请求进行缓存:

baseQuery: fetchBaseQuery({
  baseUrl: `${process.env.NEXT_PUBLIC_PROTOCOL || 'https://'}${process.env.NEXT_PUBLIC_VERCEL_URL}/api`,
  headers: {
    'x-telegram-query': typeof window !== 'undefined' ? window.Telegram.WebApp.initData : '',
  },
  cache: 'no-store',
  next: { revalidate: 0 }, // 强制禁用Next.js缓存
}),

3. 调整getInitialProps的缓存策略

Next.js生产环境会缓存getInitialProps的执行结果,需在返回值中添加revalidate字段控制缓存有效期:

export const initialPagePropsWithCompanies = wrapper.getInitialProps((store: AppStore) => async () => {
  store.dispatch(api.endpoints.getHomePage.initiate(undefined, { forceRefetch: true }));
  await Promise.all(store.dispatch(api.util.getRunningQueriesThunk()));
  return { 
    props: {}, 
    revalidate: 5 // 每5秒重新生成页面数据
  };
});

更推荐的方式:改用getServerSideProps替代getInitialProps,该API默认每次请求都执行,不会缓存结果:

export const getServerSideProps = wrapper.getServerSideProps((store) => async () => {
  store.dispatch(api.endpoints.getHomePage.initiate(undefined, { forceRefetch: true }));
  await Promise.all(store.dispatch(api.util.getRunningQueriesThunk()));
  return { props: {} };
});

4. 配置响应头禁用边缘缓存(如Vercel部署)

如果部署在Vercel等平台,可能存在边缘层缓存,需在服务端设置Cache-Control头:

export const initialPagePropsWithCompanies = wrapper.getInitialProps((store: AppStore) => async ({ res }) => {
  if (res) {
    // 设置响应头禁用缓存
    res.setHeader('Cache-Control', 'no-store, max-age=0, must-revalidate');
  }
  store.dispatch(api.endpoints.getHomePage.initiate(undefined, { forceRefetch: true }));
  await Promise.all(store.dispatch(api.util.getRunningQueriesThunk()));
  return { props: {} };
});

内容的提问来源于stack exchange,提问作者acidernt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 02:17:20