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 应用程序中的具体需求,平衡用户体验和性能。

相关推荐
bysking24 分钟前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
September_ning5 小时前
React.lazy() 懒加载
前端·react.js·前端框架
晴天飛 雪5 小时前
React 守卫路由
前端框架·reactjs
web行路人5 小时前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱0015 小时前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
Rattenking7 小时前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
一ge科研小菜鸡8 小时前
React前端框架:现代网页开发的基石(附带构建简单任务管理应用案例代码)
前端框架
熊的猫8 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
小牛itbull13 小时前
ReactPress:重塑内容管理的未来
react.js·github·reactpress
前端青山18 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js