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

Next.js 13 从 Sanity v3 获取数据时存在 stale(脏缓存数据)问题求助

Next.js 13 从 Sanity v3 获取数据时存在 stale(脏缓存数据)问题求助

兄弟我太懂你这种缓存不更新的抓狂感了!我之前用Next13搭Sanity博客的时候也踩过几乎一模一样的坑,咱们一步步来给你排查解决:

首先搞清楚核心问题:Next13的静态渲染缓存

你的Home页面是用App Router的服务器组件写的,Next13默认会把这种async服务器组件预渲染成静态页面——也就是说,第一次构建后的数据就被缓存死了,哪怕Sanity里的数据改了,前端还是会用旧的缓存内容,硬刷新都没用!

解决方案1:强制页面动态渲染

直接在你的page.tsx顶部加一行配置,告诉Next.js每次请求都要重新拉取数据,别用静态缓存:

// 放在page.tsx的最顶部,import语句之后
export const dynamic = 'force-dynamic';
// 或者用另一种写法,效果一样:
// export const revalidate = 0;

这样每次用户访问页面,都会重新执行client.fetch去Sanity拿最新数据,不会再用之前的静态缓存。

解决方案2:修改Sanity查询,过滤草稿文档

你说在Sanity里撤下了一篇文档,其实撤下的文档会变成草稿状态(ID以drafts.开头),而你的原始查询*[_type == "post"]会把草稿和已发布的文档都拉回来(如果你的client带了有权限读草稿的token),所以得在查询里过滤掉草稿:

*[_type == "post" && !(_id in path("drafts.**"))] {
  ...,
  description,
  author->,
  categories[]->
} | order(_createdAt desc)

加个!(_id in path("drafts.**"))就能确保只拉取已发布的正式内容,撤下的草稿就不会再出现在结果里了。

解决方案3:检查Sanity Client的配置细节

看看你的client配置里这几个点:

  • apiVersion:必须是YYYY-MM-DD的日期格式,建议用最近的日期(比如2024-05-20),旧的api版本可能会有兼容性问题,导致数据同步异常
  • token:你把token放在NEXT_PUBLIC_前缀下是会暴露给前端的,如果只是拉取公开的已发布内容,其实完全不需要token!删掉token试试,避免因为权限问题拉到不该拉的草稿数据
  • useCdn:你已经设成false了,这个没问题,关掉CDN就不会用Sanity的边缘缓存了

额外:如果想实现实时更新(不用刷新页面)

要是你想做到Sanity里改完内容,前端自动刷新,不用用户手动刷新,可以用Sanity的订阅功能:把BlogList改成客户端组件,然后在里面用client.subscribe监听数据变化,比如:

// BlogList.tsx 改成客户端组件,顶部加'use client'
'use client';

import { useEffect, useState } from 'react';
import { client } from '@/lib/sanity.client';
import { groq } from 'next-sanity';

const postQuery = groq`*[_type == "post" && !(_id in path("drafts.**"))] {
  ...,
  description,
  author->,
  categories[]->
} | order(_createdAt desc)`;

export default function BlogList() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    // 订阅数据变化
    const subscription = client.subscribe(postQuery).subscribe({
      next: (data) => setPosts(data),
      error: (err) => console.error('订阅出错:', err),
    });

    // 组件卸载时取消订阅
    return () => subscription.unsubscribe();
  }, []);

  // 渲染逻辑...
}

这样Sanity里的数据一更新,前端就会自动同步,不用刷新页面。

先把前三个解决方案试一遍,应该就能解决你的 stale 数据问题了!

备注:内容来源于stack exchange,提问作者Haris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 13:38:07