切換顯示語言

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您可以在頁面元件及其子元件中自由使用此類 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 和離岸的大型專案中您是否遇到任何技術問題或擔心如何解決這些問題?

案例研究