Skip to content

template.js

模板文件与 layout 类似,它封装布局或页面。与跨路由持续存在并维护状态的布局不同,模板被赋予一个唯一的键,这意味着子客户端组件在导航时重置其状态。

¥A template file is similar to a layout in that it wraps a layout or page. Unlike layouts that persist across routes and maintain state, templates are given a unique key, meaning children Client Components reset their state on navigation.

它们在以下情况下非常有用:

¥They are useful when you need to:

  • 导航时重新同步 useEffect

    ¥Resynchronize useEffect on navigation.

  • 导航时重置子客户端组件的状态。例如,一个输入字段。

    ¥Reset the state of a child Client Components on navigation. For example, an input field.

  • 更改默认框架行为。例如,布局内的 Suspense 边界仅在首次加载时显示回退,而模板会在每次导航时显示回退。

    ¥To change default framework behavior. For example, Suspense boundaries inside layouts only show a fallback on first load, while templates show it on every navigation.

惯例

¥Convention

可以通过从 template.js 文件导出默认的 React 组件来定义模板。该组件应该接受 children 属性。

¥A template can be defined by exporting a default React component from a template.js file. The component should accept a children prop.

tsx
export default function Template({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>
}

在嵌套方面,template.js 在布局及其子布局之间渲染。这是一个简化的输出:

¥In terms of nesting, template.js is rendered between a layout and its children. Here's a simplified output:

属性

¥Props

children(必需的)

¥children (required)

模板接受 children 属性。

¥Template accepts a children prop.

行为

¥Behavior

  • 服务器组件:默认情况下,模板是服务器组件。

    ¥Server Components: By default, templates are Server Components.

  • 使用导航:模板会收到一个唯一的键,用于标识其自身的段级别。当该段(包括其动态参数)发生更改时,它们会重新挂载。在更深的段内导航不会重新挂载更高级别的模板。搜索参数不会触发重新挂载。

    ¥With navigation: Templates receive a unique key for their own segment level. They remount when that segment (including its dynamic params) changes. Navigations within deeper segments do not remount higher-level templates. Search params do not trigger remounts.

  • 状态重置:模板内的任何客户端组件都会在导航时重置其状态。

    ¥State reset: Any Client Component inside the template will reset its state on navigation.

  • 重新运行效果:像 useEffect 这样的效果将在组件重新挂载时重新同步。

    ¥Effect re-run: Effects like useEffect will re-synchronize as the component remounts.

  • DOM 重置:模板内的 DOM 元素将被完全重新创建。

    ¥DOM reset: DOM elements inside the template are fully recreated.

导航和重新挂载期间的模板

¥Templates during navigation and remounting

本节演示模板在导航期间的行为。它会逐步显示每次路由更改时哪些模板重新挂载以及原因。

¥This section illustrates how templates behave during navigation. It shows, step by step, which templates remount on each route change and why.

使用此项目树:

¥Using this project tree:

app
├── about
│   ├── page.tsx
├── blog
│   ├── [slug]
│   │   └── page.tsx
│   ├── page.tsx
│   └── template.tsx
├── layout.tsx
├── page.tsx
└── template.tsx

/ 开始,React 树大致如下所示。

¥Starting at /, the React tree looks roughly like this.

注意:示例中显示的 key 值仅供参考,你应用中的值可能有所不同。

¥Note: The key values shown in the examples are illustrative, the values in your application may differ.

导航至 /about(第一个段更改),根模板键更改,模板重新挂载:

¥Navigating to /about (first segment changes), the root template key changes, it remounts:

导航至 /blog(第一个段更改),根模板键更改,模板重新挂载,博客级模板也重新挂载:

¥Navigating to /blog (first segment changes), the root template key changes, it remounts and the blog-level template mounts:

在同一个第一个段内导航至 /blog/first-post(子段更改),根模板键不变,但博客级模板键更改,模板重新挂载:

¥Navigating within the same first segment to /blog/first-post (child segment changes), the root template key doesn't change, but the blog-level template key changes, it remounts:

导航至 /blog/second-post(第一个段相同,子段不同),根模板键不变,但博客级模板键更改,模板再次重新挂载:

¥Navigating to /blog/second-post (same first segment, different child segment), the root template key doesn't change, but the blog-level template key changes, it remounts again:

版本历史

¥Version History

版本更改
v13.0.0template 已引入。