主题
Template
Template vs Layout
layout.tsx(持久化布局):- 在同一路由段内导航时会保留该布局及其内部的 client component 状态,不会在每次子页面切换时重新挂载。适用于 header、侧栏、导航栏、保持滚动/输入状态等需要跨页面保留状态的 UI。文件名:
layout.tsx。 - 示例:
- 在同一路由段内导航时会保留该布局及其内部的 client component 状态,不会在每次子页面切换时重新挂载。适用于 header、侧栏、导航栏、保持滚动/输入状态等需要跨页面保留状态的 UI。文件名:
tsx
// app/dashboard/layout.tsx
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div>
<header>Dashboard Header (preserved)</header>
<aside>Sidebar (preserved)</aside>
<main>{children}</main>
</div>
)
}template.tsx(非持久化模板):- 每次导航到其子路由时会重新渲染并重新挂载其子树,导致内部的 client component 状态被重置。适用于需要在每次页面进入时重置状态或强制刷新子组件的场景(例如需要清空表单、重置订阅等)。文件名:
template.tsx。 - 示例:
- 每次导航到其子路由时会重新渲染并重新挂载其子树,导致内部的 client component 状态被重置。适用于需要在每次页面进入时重置状态或强制刷新子组件的场景(例如需要清空表单、重置订阅等)。文件名:
tsx
// app/dashboard/template.tsx
export default function DashboardTemplate({ children }: { children: React.ReactNode }) {
return (
<div>
<header>Dashboard Header (recreated on each navigation)</header>
<main>{children}</main>
</div>
)
}用哪一个?
- 优先使用
layout.tsx:大多数共享 UI 场景(导航、侧栏、持久化动画/滚动/表单输入)都应使用layout,以获得更好的用户体验和性能。 - 使用
template.tsx:当你确实需要在每次路由变化时重置子树(清理副作用、确保从干净状态开始)时使用。 - 混用:可以在不同层级混用
layout与template,通过在特定路由段使用template来局部关闭持久化。
注意
loading.tsx、error.tsx、not-found.tsx等边界组件与layout/template一起工作时,需注意它们的段级作用域和用户体验。- 对于 Server Component 与 Client Component 的边界,
layout会影响 client component 的挂载周期;把需要保留状态的部分放在layout中的 client component 内。
