从 NextJS 异步服务器组件访问 Supabase 的数据库时如何跳过缓存 GET API 请求?

问题描述 投票:0回答:1

我正在研究的示例非常简单。我有一个非常简单的 NextJS 应用程序(使用应用程序目录),它连接到 Supabase 数据库。这是我第一次尝试使用app目录——我以前专业使用过NextJS,但只使用过页面路由器。

为了了解一些背景信息,我的应用程序允许用户创建活动并将客人添加到这些活动中。所有更新均以非常标准的方式在客户端组件上完成:

  • 用户单击“更新”按钮
  • 使用其 API 向 Supabase 发出请求
  • 我检查 Supabase 并发现我的数据库(总是)正确更新

读取全部在异步服务器组件中完成:

  • 异步服务器组件使用 Supabase SELECT API 来读取数据库表
  • 结果被传递到客户端组件以实际将它们渲染到 UI 中

问题在这里:尽管我可以看到数据库具有所有正确的行,但我得到的似乎是使用 SELECT API 在服务器组件中返回的陈旧版本。这会导致 UI 显示陈旧数据,并使我的应用程序几乎无法使用。我尝试记录 API 返回的结果,并且日志还显示过时的数据 - 与进入实际 UI 和客户端组件的数据相同。

有趣的是,我注意到,如果我更新一些代码并触发模块刷新,我就会开始获取最新数据。我深入研究了 NextJS 缓存,发现存在大量与缓存相关的常见混乱,其他人也看到了这个问题。然而,我已经尝试了他们所有的解决方法,但我无法避免这种缓存。目前,我不确定这只是 Next,还是 Supabase 也在做一些让缓存清除变得特别具有挑战性的事情。

这是我到目前为止所尝试的,正如 NextJS 文档和 GitHub 问题中所建议的那样:

    向执行 SELECT 请求的服务器组件添加了
  • export const revalidate = 0
    export const dynamic = 'force-dynamic'
    
    
  • unstable_noStore()
     到不同的根组件,包括获取数据的核心服务器组件
  • 尝试修改 Supabase 中的
  • createClient
     调用以创建全局 
    fetch
     覆盖,这基本上只是标准浏览器获取,没有额外的缓存魔法
无论我做什么,我的下一个缓存都会持续存在。如果我重新启动下一个服务器,缓存就会被破坏,并且我会显示正确的数据。

如果有一个明显的解决方案,有人可以指出我缺少什么吗?

next.js caching supabase
1个回答
0
投票
您遇到的问题源于对 Next.js 中缓存如何工作的误解。

一旦数据被缓存,它将一直保持这种状态,直到您显式触发缓存的重新验证。

让我将其分为两个简单的步骤:

    获取数据时,为其分配标签。
  1. 更新数据后(无论是插入、更新还是删除),重新验证标记,以便 Next.js 可以重新获取更新的数据。
使用 Supabase,您可以按如下方式实现此方法:

这是我在自己的项目中使用的一个示例:

import type { Database } from "@/types/database"; import { createBrowserClient } from "@supabase/ssr"; import { unstable_noStore } from "next/cache"; const fetchWithTags = ( input: RequestInfo | URL, init?: RequestInit, tag?: string, ): Promise<Response> => { return fetch(input, { ...init, next: { ...(init?.next || {}), tags: tag ? [tag] : [], }, }); }; interface Props { tag?: string; noStore?: boolean; } export const createClient = ( { tag, noStore }: Props = { tag: undefined, noStore: false }, ) => { if (noStore) { unstable_noStore(); } return createBrowserClient<Database>( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { global: { fetch: (input: RequestInfo | URL, init?: RequestInit) => fetchWithTags(input, init, tag), }, }, ); };
创建 Supabase 客户端时,您可以像这样指定标签:

createClient({ tag: "main/hero" });
然后,在修改数据后,您可以在路由处理程序中或任何适当的地方重新验证标记:

... revalidateTag("main/hero"); ...
这将确保 Next.js 在发生更改时获取最新数据。

或者,如果您真的不关心设置标签,只需使用

noStore

 选项,这样所有内容都不会被缓存。

© www.soinside.com 2019 - 2024. All rights reserved.