NextJS 13 App目录动态设置元数据如何避免重复请求?
NextJS 13 App目录动态元数据避免重复请求的解决方法
在App目录下,服务端组件的generateMetadata和页面组件本身如果都调用数据接口,默认会触发两次请求,但可以通过缓存机制解决,这并非官方设计疏漏,而是需要合理利用框架提供的缓存能力:
方法一:利用React.cache缓存数据获取函数
将数据获取逻辑用React.cache包装,确保两次调用返回同一个Promise,从而避免重复请求接口。
示例代码:
// 导入React的cache方法 import { cache } from 'react'; // 缓存getPerson函数 const getPerson = cache(async (id) => { // 这里替换成你的实际接口请求逻辑 const response = await fetch(`https://your-api.com/person/${id}`); if (!response.ok) throw new Error('Failed to fetch person'); return response.json(); }); // 动态生成元数据 export async function generateMetadata({ params }) { const person = await getPerson(params.id); return { title: person.name, description: person.description, }; } // 页面组件 export default async function PersonPage({ params }) { const person = await getPerson(params.id); return ( <div> <h1>{person.name}</h1> <p>{person.description}</p> </div> ); }
方法二:利用NextJS的fetch默认缓存
如果你的数据获取是通过原生fetch实现的,NextJS在App目录的服务端组件中默认会对GET请求进行缓存(cache: 'force-cache'是默认值),只要两次请求的URL和参数完全一致,框架会自动复用缓存结果,无需额外处理。
示例代码:
// 直接使用fetch,默认缓存 async function getPerson(id) { const response = await fetch(`https://your-api.com/person/${id}`); if (!response.ok) throw new Error('Failed to fetch person'); return response.json(); } export async function generateMetadata({ params }) { const person = await getPerson(params.id); return { title: person.name, description: person.description, }; } export default async function PersonPage({ params }) { const person = await getPerson(params.id); return ( <div> <h1>{person.name}</h1> <p>{person.description}</p> </div> ); }
需要注意的是,如果你的接口需要实时数据,可以通过设置cache: 'no-store'或者next: { revalidate: 0 }来禁用缓存,但此时仍可通过React.cache确保同一次请求周期内只调用一次接口。
内容的提问来源于stack exchange,提问作者Twisted Tea
相关产品推荐
相关产品推荐

