layout.js
布局 (layout) 是在路由之间共享的 UI。
根布局 (root layout) 是位于根 app
目录中的最顶层布局。它用于定义 <html>
和 <body>
标签以及其他全局共享的 UI。
属性
children
(必需)
布局组件应该接受并使用 children
属性。在渲染过程中,children
将被填充为布局所包装的路由片段。这些主要是子 布局 (如果存在) 或 页面 的组件,但在适用的情况下也可能是其他特殊文件,如 Loading 或 Error。
params
(可选)
从根段到该布局的 动态路由参数 对象。
示例 | URL | params |
---|---|---|
app/dashboard/[team]/layout.js | /dashboard/1 | { team: '1' } |
app/shop/[tag]/[item]/layout.js | /shop/1/2 | { tag: '1', item: '2' } |
app/blog/[...slug]/layout.js | /blog/1/2 | { slug: ['1', '2'] } |
例如:
注意事项
根布局
app
目录必须包含一个根app/layout.js
。- 根布局必须定义
<html>
和<body>
标签。- 你不应手动添加
<head>
标签,如<title>
和<meta>
到根布局。相反,你应该使用 元数据 API,它会自动处理高级需求,如流式传输和去重<head>
元素。
- 你不应手动添加
- 你可以使用 路由组 来创建多个根布局。
- 在多个根布局之间导航将导致完整的页面加载 (而不是客户端导航)。例如,从使用
app/(shop)/layout.js
的/cart
导航到使用app/(marketing)/layout.js
的/blog
将导致完整的页面加载。这仅适用于多个根布局。
- 在多个根布局之间导航将导致完整的页面加载 (而不是客户端导航)。例如,从使用
布局不接收 searchParams
与 页面 不同,布局组件不接收 searchParams
属性。这是因为共享布局在导航期间 不会重新渲染,这可能导致在导航之间出现过时的 searchParams
。
当使用客户端导航时,Next.js 会自动只渲染两个路由之间共同布局下面的页面部分。
例如,在以下目录结构中,dashboard/layout.tsx
是 /dashboard/settings
和 /dashboard/analytics
的共同布局:
当从 /dashboard/settings
导航到 /dashboard/analytics
时,/dashboard/analytics
中的 page.tsx
将在服务器上重新渲染,而 dashboard/layout.tsx
将不会重新渲染,因为它是两个路由之间共享的 UI。
这种性能优化允许共享布局的页面之间的导航更快,因为只需要运行页面的数据获取和渲染,而不是整个路由,其中可能包括获取自己数据的共享布局。
因为 dashboard/layout.tsx
不会重新渲染,布局服务器组件中的 searchParams
属性在导航后可能变得过时。
相反,使用页面的 searchParams
属性或在客户端组件中使用 useSearchParams
hook,它会在客户端使用最新的 searchParams
重新渲染。
布局无法访问 pathname
布局无法访问 pathname
。这是因为布局默认是服务器组件,并且 在客户端导航期间不会重新渲染,这可能导致 pathname
在导航之间变得过时。为了防止过时,Next.js 需要重新获取路由的所有段,从而失去缓存的好处并增加导航时的 RSC 负载 大小。
相反,你可以将依赖于 pathname 的逻辑提取到一个客户端组件中,并将其导入到你的布局中。由于客户端组件在导航期间会重新渲染 (但不会重新获取),你可以使用 Next.js hook,如 usePathname
来访问当前 pathname 并防止过时。
常见的 pathname
模式也可以通过 params
属性实现。
查看 示例 部分以获取更多信息。
版本历史
版本 | 变更 |
---|---|
v13.0.0 | 引入了 layout 。 |