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

相关推荐
zqx_711 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
笑非不退1 天前
前端框架对比和选择
前端框架
TonyH20021 天前
webpack 4 的 30 个步骤构建 react 开发环境
前端·css·react.js·webpack·postcss·打包
掘金泥石流1 天前
React v19 的 React Complier 是如何优化 React 组件的,看 AI 是如何回答的
javascript·人工智能·react.js
lucifer3111 天前
深入解析 React 组件封装 —— 从业务需求到性能优化
前端·react.js
老章学编程i1 天前
Vue工程化开发
开发语言·前端·javascript·vue.js·前端框架
秃头女孩y2 天前
React基础-快速梳理
前端·react.js·前端框架
Small-K2 天前
前端框架中@路径别名原理和配置
前端·webpack·typescript·前端框架·vite
sophie旭2 天前
我要拿捏 react 系列二: React 架构设计
javascript·react.js·前端框架