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

相关推荐
screct_demo5 小时前
詳細講一下在RN(ReactNative)中,6個比較常用的組件以及詳細的用法
javascript·react native·react.js
光头程序员14 小时前
grid 布局react组件可以循数据自定义渲染某个数据 ,或插入某些数据在某个索引下
javascript·react.js·ecmascript
limit for me14 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者14 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架
VillanelleS17 小时前
React进阶之高阶组件HOC、react hooks、自定义hooks
前端·react.js·前端框架
eason_fan18 小时前
分析vue3源码23(异步组件实现)
vue.js·前端框架·源码阅读
傻小胖18 小时前
React 中hooks之useInsertionEffect用法总结
前端·javascript·react.js
有来技术1 天前
从0到1构建开源 vue-uniapp-template:使用 UniApp + Vue3 + TypeScript 和 VSCoe、CLI 开发跨平台移动端脚手架
前端框架
flying robot1 天前
React的响应式
前端·javascript·react.js
GISer_Jing2 天前
React+AntDesign实现类似Chatgpt交互界面
前端·javascript·react.js·前端框架