Next.js 14:Layouts 和 Templates

Next.js 中的新应用程序路由器引入了两种用于构建 UI 的新文件约定:LayoutsTemplates。这些可以用来组织网页、跟踪更改并使网站运行得更快。

在开发中容易混淆使用模板和布局,而忽略了它们之间的用例和区别。本篇文章将以浅显易懂的方式阐述 LayoutsTemplates 的区别,如何进行设置,并推荐适合使用它们的最佳场景。

深入理解 Layouts 与 Templates

在 Next.js 中,Layouts 像是持久的 UI 外壳,将应用的各个页面紧紧包裹,是一种将整个应用程序中多个页面共同的 UI 抽象为组件的方式,例如,像页脚这样的 UI 元素可能在整个应用程序中重复出现。Layouts 允许开发者设定一种在不同路由间保持完整的、统一的、无需再次渲染的通用结构。对于如 HeaderFooter 以及侧边栏这类需要在用户浏览应用过程中保持一致的组件来说,这特别实用。

  • 在共享相同布局的不同页面之间导航时,布局组件不会重新渲染。
  • 导航时,布局中的状态仍将被保留并保持完全交互。

模板和布局是同义词,都是在多个页面上重复出现的共享 UI。但有一项关键的不同:每当用户跳转至新的页面时,模板都会全新地挂载一次。这个重新挂载的过程将重置所有的组件状态和效果,使每一次页面的过渡都能有一个全新的起点。

  • 布局在路由之间导航时保留状态,不会重新渲染。
  • 模板不同,它们在页面路由之间导航时重新渲染,并为每个子元素创建新实例。

如何定义 Layouts 和 Templates

如果要定义一个 layout,需要在一个名为 layout.jslayout.tsx 的文件中创建一个 React 组件。这个组件应包含一个 children 属性,可以将子 layout 或者页面整合到一起。

以下是一个简单的 layout 组件示例:

javascript 复制代码
// app/layout.tsx

import Header from "./Header";
import Footer from "./Footer";

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <div>
      <Header />
      {children}
      <Footer />
    </div>
  );
}

模板 Template 的定义是通过在一个名为 template.jstemplate.tsx 的文件中导出一个默认的 React 组件来实现的。与 layout 类似,该组件也应能接收并渲染 children 属性。

以下是一个简单的 template 组件示例:

javascript 复制代码
// app/template.tsx

"use client";
import { useEffect } from "react";

export default function Template({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    console.log("Log page view");
  }, []);
  return <div>{children}</div>;
}

小提示:一个单独的路由可以包含布局和模板,其中布局充当外部外壳,将模板包裹在其中。

组件重新挂载:布局与模板

考虑一个最简单的示例,展示在使用布局和模板时组件重新挂载的情况。首先使用 create-next-app 创建并初始化一个 Next.js 项目。

初始化身份验证界面

app 文件夹下创建目录 auth

auth 目录下,添加 login 的子目录,在其中添加一个文件 page.tsx 来构建登录页面:

javascript 复制代码
export default function RegisterPage() {
  return <h1>Register</h1>;
}

实现共享布局

在目录 auth 下,创建一个文件 layout.tsx ,其中包含用户反馈输入和导航链接:

javascript 复制代码
"use client";
import Link from "next/link";
import { useState } from "react";

export default function AuthLayout({ children }) {
  const [feedback, setFeedback] = useState("");
  return (
    <div>
      <label htmlFor="feedback">Your UX Feedback</label>
      <input
        id="feedback"
        value={feedback}
        onChange={(e) => setFeedback(e.target.value)}
      />
      <nav>
        <Link href="/auth/login">Login</Link>
        <Link href="/auth/register">Register</Link>
      </nav>
      {children}
    </div>
  );
}

在登录和注册路由之间切换,并观察反馈输入框的状态是否得以保留。

布局到模板

将文件名从 layout.tsx 更改为 template.tsx。此更改意味着在登录和注册页面之间切换时,反馈输入的状态会被重置,表明组件在每次路由更改时都会重新加载。

在布局和模板之间做决策

在开发 Web 应用程序时,将不可避免地需要在布局和模板之间做出选择。下面是一些建议,希望可以帮助做出明智的决策:

选择布局时

  • 保证一致性:通过使用布局,在整个应用程序中提供统一的外观和行为。它们非常适合用于诸如页眉和页脚之类的常见元素。
  • 维护状态:布局有助于保持状态和行为的持续性,例如用户登录状态,在导航过程中保持不变。
  • 提高性能:通过最小化重渲染和简化状态管理,布局有助于提升性能。

选择模板时

  • 隔离性:当组件不应共享状态或行为时,模板是有用的,因为它们在导航时会重新加载和重新渲染。
  • 行为灵活性 :如果需要在用户导航到组件时触发特定效果或状态更改,模板提供了这种功能。例如,它们适用于:
    • 使用 useEffect 跟踪页面浏览量。
    • 使用 useState 管理的每个页面独立的反馈表单。
  • 修改默认行为:模板可以修改某些功能在框架内的工作方式。例如,它们可以控制在页面转换期间在 Suspense 边界中显示备用 UI,而布局无法实现。

总之,对于页面中的静态和一致元素,首选布局以获得性能和状态管理方面的优势。而模板则适用于创建独立、与状态无关的组件实例,在每次导航时都能发挥效果和状态初始化功能。

总结

总的来说,Next.js 的布局和模板为 UI 构建提供了不同的方法:

  • 布局提供了一个稳定的 UI 框架,减少重新渲染并在导航过程中保持状态,非常适合一致的整站组件。
  • 相比之下,模板在每次访问页面时重置状态并重新渲染,适用于独特的、页面特定的行为。

在 Next.js 应用程序中,为了效率和一致性,选择布局 layout;而对于需要独立、与状态无关的组件,在导航时需要新鲜状态的情况,选择模板 template。正确的选择取决于每个页面在 Next.js 应用程序中的具体需求,平衡用户体验和性能。

相关推荐
前端三叶草25 分钟前
静态分析:现代前端脚手架路由梳理
前端·前端框架
╰つ゛木槿2 小时前
Vue与React区别分析
前端·vue.js·react.js
旭久11 小时前
react+antd中做一个外部按钮新增 表格内部本地新增一条数据并且支持编辑删除(无难度上手)
前端·javascript·react.js
windyrain11 小时前
ant design pro 模版简化工具
前端·react.js·ant design
GISer_Jing11 小时前
React-Markdown详解
前端·react.js·前端框架
太阳花ˉ11 小时前
React(九)React Hooks
前端·react.js
旭久14 小时前
react+antd封装一个可回车自定义option的select并且与某些内容相互禁用
前端·javascript·react.js
阿丽塔~14 小时前
React 函数组件间怎么进行通信?
前端·javascript·react.js
前端菜鸟来报道15 小时前
前端react 实现分段进度条
前端·javascript·react.js·进度条
傻球17 小时前
Jotai 使用详解:React 轻量级状态管理库
前端·react.js