Skip to content

Template

Template vs Layout

  • layout.tsx(持久化布局):
    • 在同一路由段内导航时会保留该布局及其内部的 client component 状态,不会在每次子页面切换时重新挂载。适用于 header、侧栏、导航栏、保持滚动/输入状态等需要跨页面保留状态的 UI。文件名:layout.tsx
    • 示例:
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
    • 示例:
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:当你确实需要在每次路由变化时重置子树(清理副作用、确保从干净状态开始)时使用。
  • 混用:可以在不同层级混用 layouttemplate,通过在特定路由段使用 template 来局部关闭持久化。

注意

  • loading.tsxerror.tsxnot-found.tsx 等边界组件与 layout/template 一起工作时,需注意它们的段级作用域和用户体验。
  • 对于 Server Component 与 Client Component 的边界,layout 会影响 client component 的挂载周期;把需要保留状态的部分放在 layout 中的 client component 内。

基于 MIT 许可发布