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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:22:44