Next.js 13 App Routes:如何避免元数据与页面组件重复获取数据?
Next.js 13 App Routes 避免重复数据请求的方案
在App Routes模式下,generateMetadata和Page组件重复调用数据获取函数的问题,可以通过以下几种方式解决:
1. 用React cache函数包装数据获取函数
React 18+ 提供的cache函数可以让相同参数的重复调用共享同一个Promise,从而避免重复发起请求。只需把你的getProducts函数用cache包装即可:
import { cache } from 'react'; // 包装getProducts函数 const getProducts = cache(async (slug: string) => { // 原有的数据获取逻辑,比如fetch请求或数据库查询 const res = await fetch(`https://api.example.com/products/${slug}`); return res.json(); }); // 后续在两个函数中正常调用,不会触发重复请求 export async function generateMetadata(params: { slug: string }) { const data = await getProducts(params.slug); return { title: data.title, // ...其他元数据配置 }; } export async function Page(params: { slug: string }) { const data = await getProducts(params.slug); return ( <> <h1>{data.title}</h1> </> ); }
2. 利用Next.js的自动缓存机制
如果你的getProducts函数内部使用fetch API,Next.js在App Router模式下默认会对fetch请求进行缓存(除非显式配置cache: 'no-store')。这种情况下,即使重复调用getProducts,实际只会发起一次请求,后续调用直接复用缓存结果。
若需要自定义缓存策略,可在fetch中配置next选项:
async function getProducts(slug: string) { const res = await fetch(`https://api.example.com/products/${slug}`, { next: { // 缓存有效期1小时 revalidate: 3600, // 标记缓存标签,方便后续主动刷新缓存 tags: [`product-${slug}`] } }); return res.json(); }
3. 封装共享数据服务层(可选)
可以把数据获取逻辑单独抽离到服务文件中,结合上述缓存方式处理,确保整个应用内相同参数的数据请求都能复用缓存,不限于generateMetadata和Page组件。
内容的提问来源于stack exchange,提问作者Tom Fan
相关产品推荐
相关产品推荐

