Next.js 13中如何仅获取一次数据并作为Props传递
解决Next.js 13 App路由中重复请求的问题
核心方案:利用React/Next.js的缓存机制复用请求结果
在App路由中,generateMetadata和页面组件均为服务端执行的异步函数,默认会发起独立请求。通过将数据获取逻辑用缓存函数包裹,可让同一次请求周期内的重复调用复用结果,彻底避免重复API请求。
步骤1:改造数据获取函数,添加缓存
修改你的screen.ssr.ts文件,根据需求选择以下两种缓存方式:
方式1:React cache(同请求内复用,稳定API)
适用于仅需在单次页面渲染中复用请求结果的场景:
// screen.ssr.ts import { cache } from 'react'; import axios from 'axios'; import { IData } from '../types/data.type'; // 用cache包裹异步函数,同一次渲染中相同参数的调用自动复用结果 export const getDataSSR = cache(async ({ id }: { id: number }) => { const response = await axios.get(`/api/screen/${id}`); return response.data as IData; });
方式2:Next.js unstable_cache(跨请求缓存,实验性API)
若需让后续用户请求相同ID时复用服务器端缓存结果,可使用该方式:
// screen.ssr.ts import { unstable_cache } from 'next/cache'; import axios from 'axios'; import { IData } from '../types/data.type'; export const getDataSSR = unstable_cache( async ({ id }: { id: number }) => { const response = await axios.get(`/api/screen/${id}`); return response.data as IData; }, ['screen-data', String(id)], // 缓存键,确保不同ID的缓存独立 { revalidate: 60 } // 可选:缓存过期时间(秒),到期自动重新获取 );
步骤2:保持原有页面代码不变
你的component.ts代码无需修改,缓存后的getDataSSR会自动复用请求结果:
import MyComponent from '@/components/screens/screen/component'; import { getDataSSR } from '@/components/screens/screen/api/screen.ssr'; import { IData } from '@/components/screens/screen/types/data.type'; export async function generateMetadata({ params }: { params: { id: string } }) { const data = await getDataSSR({ id: Number(params.id) }) as IData; return { title: `${data?.data?.details?.userProfile?.fullName}`, }; } const ComponentPage = async ({ params }: { params: { id: string } }) => { // 此处调用会复用generateMetadata中已获取的结果,不会重复发请求 const data = await getDataSSR({ id: Number(params.id) }) as IData; return <MyComponent id={params.id} data={data} />; }; export default ComponentPage;
原理说明
- React
cache:在单次服务端渲染请求周期内缓存异步函数返回值,相同参数的调用直接复用缓存,无额外配置成本。 - Next.js
unstable_cache:将缓存存储在服务器端,支持跨用户请求复用,需通过缓存键区分不同数据,可配置过期时间实现自动刷新。
其他方案排除原因
- RTK Query暂不支持React Server Components,无法在服务端组件中使用其缓存机制。
- App路由无
getServerSideProps的直接替代,但服务端组件的异步数据获取能力配合缓存机制,完全可实现相同效果。
内容的提问来源于stack exchange,提问作者marklovescoding
相关产品推荐
相关产品推荐

