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

如何在Next.js App Router中复用单次DB/API调用至generateMetadata与页面组件

解决Next.js 14 App Router中generateMetadata与组件重复查询数据库的问题

当然可以复用一次数据库查询的结果,核心思路是通过缓存机制让generateMetadata和组件共享同一份查询数据,以下是两种实用方案:

方案一:使用Next.js的unstable_cache(推荐,针对服务端缓存优化)

将数据库查询逻辑封装成带缓存的函数,这样两次调用都会命中缓存,仅执行一次数据库请求:

import { unstable_cache } from 'next/cache';
import prisma from '@/lib/prisma';

// 封装带缓存的博客查询函数
const getBlogBySlug = unstable_cache(
  async (slug: string) => {
    return prisma.blog.findUnique({
      where: { slug },
      include: { author: true } // 按需包含关联数据
    });
  },
  ['blog-detail'], // 唯一缓存键,用于区分不同类型的缓存
  { revalidate: 60 } // 缓存有效期(秒),可根据业务调整
);

// 在generateMetadata中调用缓存函数
export async function generateMetadata({ params }: { params: { slug: string } }) {
  const blog = await getBlogBySlug(params.slug);
  if (!blog) return { title: '博客不存在' };

  return {
    title: blog.title,
    description: blog.excerpt
  };
}

// 在页面组件中调用同一个缓存函数
export default async function BlogDetailPage({ params }: { params: { slug: string } }) {
  const blog = await getBlogBySlug(params.slug);
  if (!blog) return <div>博客不存在</div>;

  return (
    <article>
      <h1>{blog.title}</h1>
      <div>{blog.content}</div>
    </article>
  );
}

unstable_cache是Next.js专为服务端渲染场景设计的缓存API,能确保相同参数的查询请求复用缓存结果,避免重复数据库调用。虽然标记为"unstable",但在Next.js 14中已经被广泛使用,后续大概率会稳定。

方案二:使用React的cache函数(通用React服务端缓存)

如果更倾向于使用原生React API,可以用React.cache包裹查询函数:

import { cache } from 'react';
import prisma from '@/lib/prisma';

// 用React.cache包裹查询函数
const getBlogBySlug = cache(async (slug: string) => {
  return prisma.blog.findUnique({
    where: { slug }
  });
});

// 后续generateMetadata和组件中的调用逻辑与方案一完全一致

React.cache会在服务端渲染时缓存相同参数的函数调用结果,同样能实现数据复用。这种方式更贴合React生态,适合不需要精细控制缓存策略的场景。

注意事项

  • 确保查询函数的参数是可序列化的(比如字符串、数字),这样缓存系统才能正确生成唯一缓存键。
  • 若博客内容需要实时更新,可调整revalidate时间(方案一),或使用缓存标签(tags参数)手动触发缓存刷新。
  • 对于完全动态的内容,可结合增量静态再生(ISR)进一步优化性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 03:37:20