那我們來說說 app router 的機制吧!App Router 是 Next 13 新介紹的一種 routing 方式,與之相對過去的方式被稱作 Pages Router,可以在官方網站左側按鈕切換兩種路由模式的 Documentation,之前預設都是將 component 放在 client 來處理,現在透過 RSC(React Server Component) 讓我們可以將 component 移到 server 來處理,那這個新的區塊就是Next 13 所新增的 App Router。
使用上來說,在 app 資料夾下面的 component 預設都會是 RSC(React Server Component) 組件,那處理上來說就可以透過它來處理一些 data fetch 的動作,如果要使用 useState, useEffect 或是事件監聽動作的話就要將該部分轉換成 client component。
實際上的差異就是你會發現 component 在使用 useState 的時候要轉成以下:
'use client';
import { useState } from 'react';
export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>++</button>
    </div>
  );
}
就是在第一行加上 'use client' 的標記,那麼你就可以簡單地將他轉換回 client component 了。
Page Router: 以檔案為單位定義頁面,該頁面相關設定必須放在外部管理、引入,較難客製化
App Router: 以資料集為單位定義頁面,該頁面所有相關設定可直接放在 folder 層級中,可高度客製化
Page Router: pages/index.tsx, pages/product.tsx
App Router: app/page.tsx, app/product/page.tsx

比較要注意的會是下面這張圖
下面的表格一樣是從 Next官方文件 搬過來的:
| 檔案名 | 作用 | 
|---|---|
| layout | 共用 UI 元件,包含該 Segment 及其子元件 | 
| page | 該路徑的主要 UI,並使路徑可以公開存取 | 
| loading | 該 Segment 及其子元件的載入中 UI | 
| error | 該 Segment 及其子元件的錯誤 UI | 
| global-error | 全域錯誤 UI | 
| route | 伺服器端 API 端點 | 
| template | 處理需要重新渲染的 Layout UI | 
| default | 處理Parallel Routes的fallback | 
<Head> component 幫助我們在頁面中客製化 SEO meta,改成透過 metadata object 來定義:
import { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: '晚安',
  description: '瑪卡巴卡',
}
 
export default function Page() {}
layout 為多個頁面之間共享的使用者界面,在導航時,版面配置保留狀態、保持互動,並且不會重新渲染,也可以被嵌套使用。
圖片來源
可以預設從layout.js檔案匯出 React 元件來定義佈局,該元件應該接受一個 Children 屬性,該屬性將在渲染期間填入子 layout(如果存在)或子頁面。
export default function DashboardLayout({
  children, // 這裡可以擺 page or layout
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      <nav></nav>
      {children}
    </section>
  )
}
巢狀結構的話大概是這樣
你可以把它想成是用來取代 Page Router 的 _app.tsx, _document.tsx,下面是比較要注意的點。
<html> 和 <body> tag,因為 NextJS 並沒有為用戶定義。我的理解就是多了個 () 來應用在 route group 的概念上,讓我們在 app 資料夾下,將 routes 按照自己的意思拆分開來,並且不影響原來 route 的解析的一種技術。
此外,我們還可以在 Route Groups 下面定義自己群組的 layout。
但要注意 path 命名不要撞到了,比如說在 group 中重複使用相同的 /about 會報錯((marketing)/about/page.js, (shop)/about/page.js 兩者會衝突)。
以上就是我大概簡略地介紹一些 App Router 的差異,還有很多細節內容都在 Next 官方文件當中,如果有興趣深入了解的話也可以直接訪問官方文件,上面介紹的概念我想已經夠讓我們將原本的 Rick and morty 列表移植到 App Router 的環境中,下一篇我們來實作看看吧!