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

如何在NextJS 13 App Router中实现页面向布局组件传数据?

Next.js 13 App Router 页面向嵌套布局传递动态标题的解决方案

在Next.js 13的App Router嵌套布局场景下,页面向布局传递动态标题可以通过以下几种实用方法实现:

方法一:使用 React Context(通用方案)

通过创建Context在页面和布局之间共享数据,适合需要传递多个数据的场景。

1. 创建标题Context

// app/users/TitleContext.tsx
'use client';

import { createContext, useContext, useState, ReactNode } from 'react';

type TitleContextType = {
  setPageTitle: (title: string) => void;
};

const TitleContext = createContext<TitleContextType | undefined>(undefined);

export function TitleProvider({ children }: { children: ReactNode }) {
  const [pageTitle, setPageTitle] = useState('');

  return (
    <TitleContext.Provider value={{ setPageTitle }}>
      {/* 布局中渲染标题 */}
      <h1>{pageTitle}</h1>
      {children}
    </TitleContext.Provider>
  );
}

export function useTitleContext() {
  const context = useContext(TitleContext);
  if (!context) {
    throw new Error('useTitleContext must be used within a TitleProvider');
  }
  return context;
}

2. 在布局中引入Provider

// app/users/layout.tsx
import { TitleProvider } from './TitleContext';

export default function UsersLayout({ children }: { children: ReactNode }) {
  return <TitleProvider>{children}</TitleProvider>;
}

3. 在页面中设置标题

// app/users/page.tsx
'use client';

import { useTitleContext } from './TitleContext';
import { useEffect } from 'react';

export default function Users() {
  const { setPageTitle } = useTitleContext();
  
  // 组件挂载后设置标题
  useEffect(() => {
    setPageTitle('Users');
  }, [setPageTitle]);

  return (
    <>
      {/* 页面内容 */}
    </>
  );
}

方法二:利用 generateMetadata + useMetadata(Next.js 原生方案,推荐)

符合App Router的设计思路,同时能同步页面元数据和布局标题。

1. 页面中定义generateMetadata

// app/users/page.tsx
export async function generateMetadata() {
  return {
    title: 'Users',
  };
}

export default function Users() {
  return (
    <>
      {/* 页面内容 */}
    </>
  );
}

2. 在布局中获取并渲染标题

// app/users/layout.tsx
'use client';

import { useMetadata } from 'next/headers';

export default function UsersLayout({ children }: { children: ReactNode }) {
  const metadata = useMetadata();
  
  return (
    <>
      <h1>{metadata.title}</h1>
      {children}
    </>
  );
}

注意:useMetadata 是Next.js 13.4+提供的客户端钩子,仅能在客户端组件中使用。

方法三:通过React插槽传递标题

无需额外依赖,利用React Children遍历实现标题传递。

1. 创建PageTitle占位组件

// app/users/PageTitle.tsx
export default function PageTitle({ children }: { children: string }) {
  return null; // 不在页面中渲染,仅作为传递载体
}

2. 在布局中提取标题

// app/users/layout.tsx
'use client';

import { useState, useEffect, ReactNode } from 'react';
import PageTitle from './PageTitle';

export default function UsersLayout({ children }: { children: ReactNode }) {
  const [pageTitle, setPageTitle] = useState('');

  useEffect(() => {
    React.Children.forEach(children, (child) => {
      if (React.isValidElement(child) && child.type === PageTitle) {
        setPageTitle(child.props.children);
      }
    });
  }, [children]);

  return (
    <>
      <h1>{pageTitle}</h1>
      {children}
    </>
  );
}

3. 在页面中使用PageTitle组件

// app/users/page.tsx
import PageTitle from './PageTitle';

export default function Users() {
  return (
    <>
      <PageTitle>Users</PageTitle>
      {/* 页面内容 */}
    </>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:12:40