当我们从 firebase 获取数据时,我想在下一个 js 服务器端页面上缓存数据。我已经知道我们可以使用
fetch
api 缓存默认数据
但我想在没有这个的情况下缓存数据,因为我没有任何 API
基本上在我的下一个 js 应用程序中,我有一个名为“[用户名]”的动态路由
因此示例网址将是“https://prozo.me/@hardikdesai”,我使用此函数通过用户名获取该用户的数据
export const getUserDetailsByUsername = async (username: string): Promise<{ userDetails: any; message?: string }> => {
const q = DB.collection('users').where('username', '==', username)
const querySnapshot = await q.get()
if (querySnapshot.empty) {
return { userDetails: null, message: 'User not found' }
}
const userDetails = querySnapshot.docs[0].data()
return { userDetails }
}
所以,我希望我获取的数据能够缓存 60 秒。并且当时不发出任何 firebase 数据库请求
页面.tsx
// sections
import { Metadata } from 'next'
import { getUserDetailsByUsername } from 'src/queries/user'
import { ProfileView } from 'src/sections/username/view'
// ----------------------------------------------------------------------
type Props = {
params: { username: string }
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
return {
title: `${decodeURIComponent(params?.username)} | Prozo`,
}
}
export default async function ProfilePage({ params }: { params: { username: string } }) {
const { userDetails } = await getUserDetailsByUsername(params?.username?.slice(3))
return <ProfileView userDetails={userDetails} />
}
Next.js 提供了一个体验式
cache
函数,旨在写入 Next.js 数据缓存,其功能与扩展 fetch
API 类似。
import { unstable_cache as cache } from "next/cache";
const getUserDetailsByUsernameImpl = async (username: string): Promise<{ userDetails: any; message?: string }> => {
const q = DB.collection('users').where('username', '==', username)
const querySnapshot = await q.get()
if (querySnapshot.empty) {
return { userDetails: null, message: 'User not found' }
}
const userDetails = querySnapshot.docs[0].data()
return { userDetails }
}
const getUserDetailsByUsername = cache(
/* fetch function */ getUserDetailsByUsernameImpl,
/* unique key */ ["getUserDetailsByUsername"],
/* options */ {
tags: ["getUserDetailsByUsername"],
revalidate: 60 * 60 * 24 /* same as fetch.revalidate */
}
)
其功能与
fetch
API 中的缓存类似,它允许设置重新验证选项来定义缓存数据何时应过时或调用 revalidateTag("getUserDetailsByUsername")
立即使缓存失效。
它接受 3 个参数:
tags
:可与 revalidateTag
一起使用的键数组。revalidate
:缓存应重新验证的时间间隔(以秒为单位)。在文档中阅读更多内容:https://nextjs.org/docs/app/api-reference/functions/unstable_cache
目前,
revalidateTag
存在局限性,不支持单个用户重新验证,例如,revalidateTag("getUserDetailsByUsername", "JohnDoe")
不可行。调用 revalidateTag("getUserDetailsByUsername")
会使所有缓存的用户失效。解决方法包括稍微重组:
const getUserDetailsByUsername = async (username) => {
const cachedFn = cache(
getUserDetailsByUsernameImpl,
[`getUserDetailsByUsername-${username}`],
{
tags: ["getUserDetailsByUsername", `getUserDetailsByUsername-${username}`],
revalidate: 60 * 60 * 24
}
)
return cachedFn(username);
}
此方法将用户名包含在缓存标记中,以便在必要时重新验证特定用户:
revalidateTag(`getUserDetailsByUsername-${username}`)