切换显示语言

Topics

Next.js Pages Router 和 App Router:澄清经常令人困惑的区别

  • column

Next.js 是一个流行的 Web 开发框架,它在 13 版中引入了新的 App Router 作为其默认路由系统。

我确信有些人参与的项目同时使用了 Pages Router 和 App Router,并且不知道该如何编写。我就是这样的!

特别是,Pages Router 和 App Router 在与应用程序开发核心相关的领域存在显著差异,例如如何根据文件结构定义路由、如何处理 URL 的动态部分、渲染如何工作以及如何从 API 中检索数据。

围绕“经常混淆”的点,我将简要列出 Pages Router 和 App Router 之间的主要区别,以作提醒!

文件路由的差异

Pages Router:将文件名转换为路径的简单方法

放在pages目录下.js, .jsx, .ts, .tsx就像文件名成为 URL 路径一样简单。

例子:src/page/about.tsx⇒ 路由是/about这将是。

App Router:按文件夹和特定文件名组织

应用路由器src/app您可以通过在其下放置文件夹和文件来进行路由。

但是,如果在用于路由的文件名中添加名为“page”的特定文件名,它将被视为与该路径对应的页面的内容。

例子:src/app/about/page.tsx⇒ 路由是/about这将是。

表征 App Router 的特殊文件

除了page.tsx之外,App Router中还有其他有意义的文件。

app/
├── page.tsx --> 页面内容。这是您最常使用的文件。
├── route.tsx --> API 定义(不能与 page.js 共存)。
├── layout.tsx --> 常用外观。
├── loading.tsx --> 加载界面。
├── error.tsx --> 错误界面。
├── global-error.tsx --> 全局错误界面。
├── template.tsx --> 常用外观(重置布局)。
├── default.tsx --> 默认界面。
└── not-found.tsx --> 抛出 notFound 函数时显示的界面。

我个人最惊讶的是 not-found.tsx。只需准备这个页面,当你访问一个不存在的 URL 时,它就会自动显示出来。它的实现如此简单,让我印象深刻。

渲染差异

Pages Router 中的组件基本都是设计在客户端交互的,服务器端的渲染主要是为了加快初始显示速度和SEO目的。useState 或者 useEffect您可以在 Page 组件及其子组件中自由使用此类 React Hooks。

另一方面,App Routerapp/组件除非明确指定,否则它将默认被视为服务器组件。。所以useState 或者 useEffect 例如React Hooks 不可用客户端操作,例如 onClick事件处理程序也不可用。

因此,要使用 App Router 创建 CSR,use client写:

use client

服务器组件和客户端组件宣告边界是。use client如果您声明它,不仅该组件而且其所有导入都将被视为客户端组件。

动态路由[○○]

Next.js 提供了一种处理“动态 URL”的机制,其中 URL 的一部分会根据用户或内容而变化,例如博客或新闻文章详细信息页面。动态路由是。

例如,假设有一个链接可以将您带到文章 A 和文章 B。

例如,捕获包含指向文章 A 和文章 B 的链接的页面
import Link from "next/link";
const linkStyle=`ext-lg font-bold border-b border-primary px-1`

export default function page() {
  return (
    <div>
      <div className="flex gap-6">
        <Link href="/post/A" className={linkStyle}>記事Aへのリンク</Link>
        <Link href="/post/B" className={linkStyle}>記事Bへのリンク</Link>
      </div>
    </div>
  );
}

链接目的地

捕获帖子/页面
帖子/B 页面的捕获

如果您想要动态路由,[slug]如果你创建一个名为post/Apost/B但您可以使用相同的模板。
*[ ] 中的命名是可选的。slug不一定非要这样

应用路由器

/app/post/[slug]/page.tsx

export default aysinc function PostPage({ params }: { params: Promise<{ slug: string }>) {
  const {slug}= await params;
  return (
    <div>
      <h1>記事: {slug}</h1>
    </div>
  );
}

params我们使用。params.slug到 URL[slug]该部分将被包括在内。

params以前参数获取不需要异步,但是从 Next.js 15 开始,改为异步。props看来你需要将其定义为 Promise 类型。

对于页面路由器

/pages/post/[slug].tsx


import { useRouter } from 'next/router';

export default function PostPage() {
  const router = useRouter();
  const { slug } = router.query;

  return (
    <div>
      <h1>記事: {slug}</h1>
    </div>
  );
}

useRouter我们使用。router.query.slug到 URL[slug]该部分的值将被输入。

如何获取 API 数据

microCMS 是 Liberogic 专栏中重点介绍的,它与 Next.js 等框架配合良好。

应用路由器

保持简单fetch或者aysnc await您可以使用

然而,use client声明此内容的文件将成为 CSR。aysnc await将不再可用!


async function getPost() {
  const res = await fetch(`https://.../api/data/`);

  // エラーハンドリング例
  if (!res.ok) {
     throw new Error(`Failed to fetch post: ${res.status}`);
  }

  return res.json();
}

被叫方

export default function Example() {
   const data = await getPost()
   // ... data を使って表示 ...
}

对于页面路由器

getStaticProps使用获得的数据props到页面组件。


export async function getServerSideProps(context) {
  // context.req, context.res などにアクセス可能
  const res = await fetch(`https://.../api/data/`, {
     headers: { Cookie: context.req.headers.cookie } // 例: Cookieを渡す
  });
  const data = await res.json();

  return {
    props: {
      data,
    },
  };
}

被叫方

export default function Example({ data }) {
  // ... data を使って表示 ...
}

了解两种路由器,掌握 Next.js!

就我而言,我使用 Next.js 的第一个项目是 App Router。

后来,当我从事另一个项目并使用 Pages Router 时,我发现自己很疑惑,“创建新页面时,文件名应该是 index.tsx 还是 page.tsx?”

本文仅涵盖了 Next.js 的一小部分,但通过研究 App Router 和 Pages Router 之间的区别,我能够在脑海中对它有一个更清晰的认识。

就我个人而言,我喜欢编写 App Router 的简单性,但我也希望能够处理 Pages Router 项目。

理想的情况是深入了解 Next.js,并能够根据项目或工作使用不同的路由器!

撰稿人

我使用 JavaScript、React 和 Next.js 开发前端项目,专注于标记语言。当我参与开发的网站成功发布时,我感到无比欣慰!我的爱好是弹吉他。我既喜欢写代码,也喜欢玩代码!

Hiratchi

前端工程师 / 2022年入职

我们以可靠的团队结构和快速的响应能力而自豪。

在 Liberogic,我们经验丰富的员工积极推动项目进展,这也是我们受到客户高度评价的原因。
我们确保项目经理和主管得到合理分配,以确保整个项目的顺利进行。 我们避免因全额承诺而导致不必要的成本增加,并将资源分配给合适的人员和合适的岗位,并以快速掌握工作内容、创建和提交预算而闻名。

请注意,我们不主动提供 SES 等现场服务。

我们支持几乎所有主流的项目管理和聊天工具,包括 Slack、Teams、Redmine、Backlog、Asana、Jira、Notion、Google Workspace、Zoom 和 Webex。

在使用 SES 和离岸的大型项目中您是否遇到任何技术问题或担心如何解决这些问题?

案例研究