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

Next.js 13服务器组件间数据共享最佳方案咨询(App Router场景)

Next.js 13 App Router 服务器组件数据共享方案

1. 根布局逐层传递 Props

根layout.tsx作为所有页面和嵌套布局的顶层父组件,可在其中统一获取全局共享数据,再通过 props 逐层传递给子组件(包括嵌套 layout 和 page)。

示例代码:

// app/layout.tsx
export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  // 根布局中获取共享数据
  const sharedData = await fetchGlobalData();

  return (
    <html lang="zh-CN">
      <body>
        {/* 将数据传递给所有子元素 */}
        {React.Children.map(children, (child) => {
          if (React.isValidElement(child)) {
            return React.cloneElement(child, { sharedData });
          }
          return child;
        })}
      </body>
    </html>
  );
}

// 嵌套 layout 中使用数据
export default async function NestedLayout({
  children,
  sharedData,
}: {
  children: React.ReactNode;
  sharedData: GlobalDataType;
}) {
  return <div className="nested-layout">{sharedData.siteName}</div>;
}

这种方式逻辑直观,适合全局基础数据共享,但深层嵌套组件需要逐层传递 props,可能存在"props drilling"问题。

2. 带缓存的服务器端数据函数

利用 Next.js 内置的请求缓存机制,封装可复用的数据获取函数,在需要数据的服务器组件中直接调用。Next.js 会自动缓存相同请求的结果,避免重复发起 API 调用。

示例代码:

// app/lib/data.ts
export async function getSharedData() {
  // 默认使用 force-cache 策略,可根据需求调整为 no-store 或 revalidate
  const res = await fetch('https://api.example.com/global-data', { cache: 'force-cache' });
  return res.json();
}

// 任意服务器组件(page 或 layout)
import { getSharedData } from '@/app/lib/data';

export default async function UserPage() {
  const sharedData = await getSharedData();
  return <div>当前站点:{sharedData.siteName}</div>;
}

该方式无需传递 props,每个组件按需获取数据,缓存机制保证性能,是大部分场景的首选方案。

3. 请求级数据存储容器

针对复杂场景,可利用 Next.js 的实验性请求存储(experimental_requestStorage)实现请求级别的数据共享,避免重复获取和 props 传递。

示例代码:

// app/lib/shared-data.ts
import { experimental_requestStorage } from 'next/server';

export async function getRequestSharedData() {
  const storage = experimental_requestStorage();
  let data = storage.get('request-shared-data');
  
  if (!data) {
    data = await fetchRequestSpecificData();
    storage.set('request-shared-data', data);
  }
  
  return data;
}

// 组件中使用
import { getRequestSharedData } from '@/app/lib/shared-data';

export default async function DeepNestedPage() {
  const data = await getRequestSharedData();
  return <div>用户会话ID:{data.sessionId}</div>;
}

这种方式能在同一请求的所有服务器组件中共享数据,且不会出现跨请求的数据污染问题,适合需要请求级上下文的场景。

方案选择建议

  • 全局基础数据:优先使用根布局传递 Props,逻辑简单直观。
  • 常规业务数据:使用带缓存的数据获取函数,开发效率高且性能有保障。
  • 请求级上下文数据:使用请求级数据存储容器,解决深层组件共享问题。

内容的提问来源于stack exchange,提问作者A.A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 22:22:34