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

相关推荐
天若有情6733 小时前
自己开发一款极简 Vanilla 原生前端框架,已开源上架 NPM & GitHub
前端框架·npm·github
空中海6 小时前
01 React Native 基础、核心组件与布局体系
javascript·react native·react.js
空中海7 小时前
05 React架构设计、项目实践与专家清单
前端·react.js·前端框架
空中海9 小时前
04 工程化、质量体系与 React 生态
前端·ubuntu·react.js
空中海9 小时前
03 性能、动画与 React Native 新架构
react native·react.js·架构
萑澈10 小时前
Ripple新前端框架的发展与AI原生全栈开发前景:架构重塑与生产力范式转移研究报告
架构·前端框架·ai-native
空中海11 小时前
02 React Native状态、导航、数据流与设备能力
javascript·react native·react.js
空中海12 小时前
04 React Native工程化、质量、发布与生态选型
javascript·react native·react.js
郑生zs14 小时前
Hooks-useEffect
react.js
光影少年14 小时前
react函数组件、类组件、纯组件、受控/非受控组件
前端·react.js·掘金·金石计划