Next.js应用路由:如何单次请求同时为页面与generateMetadata传参?
优化Next.js App Router中重复API请求的方案
你的当前实现确实会发起两次API请求——generateMetadata和页面组件各自调用了getProduct,二者是独立执行的,所以会触发两次fetch。这显然不是最优解,下面提供针对性的优化方案:
最优实现:使用React cache 缓存请求
通过React的cache函数包装数据获取函数,确保相同参数的请求只会发起一次,两次调用会复用同一个Promise结果,这也是Next.js官方推荐的解决这类重复请求问题的方式。
修改后的代码:
import { Metadata, ResolvingMetadata } from "next" import { cache } from 'react' import Product from "@/components/Product/product.component" type Props = { params: { ean: string } } // 用cache包装getProduct,缓存相同参数的请求 const getProduct = cache(async (ean: string) => { const res = await fetch(process.env.API_URL + `/v1/products/${ean}`) // 建议添加错误处理,避免请求失败导致页面崩溃 if (!res.ok) throw new Error('获取商品信息失败') return res.json() }) export async function generateMetadata({ params: { ean } }: Props): Promise<Metadata> { const product = await getProduct(ean) return { title: product.name, } } export default async function Page({ params: { ean } }: Props) { const product = await getProduct(ean) return <Product product={product} /> }
这个方案会在同一个请求周期内复用数据,确保只发起一次API调用,同时满足generateMetadata和页面组件的数据需求,完全匹配你的场景。
补充说明
如果尝试在页面组件顶层获取数据后直接传递给generateMetadata,是不可行的——因为generateMetadata和页面组件是并行执行的,二者无法直接共享数据,所以cache方案是当前需求下的唯一最优解。
内容的提问来源于stack exchange,提问作者jorgeju4rez
相关产品推荐
相关产品推荐

