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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:27:42