template.js
**模板**文件类似于布局,因为它包装了一个布局或页面。与跨路由持久化并维护状态的布局不同,模板被赋予唯一的键,这意味着子客户端组件会在导航时重置其状态。
它们在您需要以下情况时很有用:
- 在导航时重新同步 `useEffect`。
- 在导航时重置子客户端组件的状态。例如,一个输入字段。
- 更改默认框架行为。例如,布局内的 Suspense 边界仅在首次加载时显示回退,而模板在每次导航时都显示它。
约定
可以通过从 `template.js` 文件中导出一个默认的 React 组件来定义模板。该组件应接受 `children` 属性。

app/template.tsx
export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}在嵌套方面,`template.js` 呈现在布局及其子项之间。这是一个简化的输出:
输出
<Layout>
{/* Note that the template is given a unique key. */}
<Template key={routeParam}>{children}</Template>
</Layout>属性
children(必填)
模板接受 `children` 属性。
输出
<Layout>
{/* Note that the template is automatically given a unique key. */}
<Template key={routeParam}>{children}</Template>
</Layout>行为
- 服务器组件:默认情况下,模板是服务器组件。
- 带导航:模板为其自身的片段级别接收唯一的键。当该片段(包括其动态参数)更改时,它们会重新挂载。在更深层片段内的导航不会重新挂载更高级别的模板。搜索参数不会触发重新挂载。
- 状态重置:模板内的任何客户端组件都会在导航时重置其状态。
- 效果重新运行:`useEffect` 等效果会随着组件重新挂载而重新同步。
- DOM 重置:模板内的 DOM 元素会被完全重新创建。
导航和重新挂载期间的模板
本节说明了模板在导航期间的行为方式。它逐步展示了在每次路由更改时哪些模板会重新挂载以及原因。
使用此项目树
app
├── about
│ ├── page.tsx
├── blog
│ ├── [slug]
│ │ └── page.tsx
│ ├── page.tsx
│ └── template.tsx
├── layout.tsx
├── page.tsx
└── template.tsx
从 / 开始,React 树大致如下所示。
注意:示例中显示的 `key` 值仅供说明,您的应用程序中的值可能不同。
输出
<RootLayout>
{/* app/template.tsx */}
<Template key="/">
<Page />
</Template>
</RootLayout>导航到 /about(第一个片段更改),根模板键更改,它会重新挂载
输出
<RootLayout>
{/* app/template.tsx */}
<Template key="/about">
<AboutPage />
</Template>
</RootLayout>导航到 /blog(第一个片段更改),根模板键更改,它会重新挂载,并且博客级别的模板会挂载
输出
<RootLayout>
{/* app/template.tsx (root) */}
<Template key="/blog">
{/* app/blog/template.tsx */}
<Template key="/blog">
<BlogIndexPage />
</Template>
</Template>
</RootLayout>在同一个第一个片段内导航到 /blog/first-post(子片段更改),根模板键不会更改,但博客级别的模板键会更改,它会重新挂载
输出
<RootLayout>
{/* app/template.tsx (root) */}
<Template key="/blog">
{/* app/blog/template.tsx */}
{/* remounts because the child segment at this level changed */}
<Template key="/blog/first-post">
<BlogPostPage slug="first-post" />
</Template>
</Template>
</RootLayout>导航到 /blog/second-post(相同的第一个片段,不同的子片段),根模板键不会更改,但博客级别的模板键会更改,它会再次重新挂载
输出
<RootLayout>
{/* app/template.tsx (root) */}
<Template key="/blog">
{/* app/blog/template.tsx */}
{/* remounts again due to changed child segment */}
<Template key="/blog/second-post">
<BlogPostPage slug="second-post" />
</Template>
</Template>
</RootLayout>版本历史
| 版本 | 更改 |
|---|---|
v13.0.0 | 引入了 `template`。 |
这有帮助吗?
