iT邦幫忙

2

Next.js - App Router 機制

  • 分享至 

  • xImage
  •  

一、React Server Components (RSC)

在 App Router 中,所有元件預設都是 Server Components。它們只在伺服器端執行,不會將任何 JavaScript 程式碼打包傳送到使用者的瀏覽器。

  • 直連資料庫:可以直接在元件內寫入 SQL 查詢、呼叫 DAO 或讀取檔案系統,不需額外經過 REST API 中介層。
  • Zero-Bundle-Size(零打包體積):像是 lodashdate-fns 或大型 Markdown 解析器等重型套件,如果只在 Server Component 使用,它們的程式碼永遠不會被下載到客戶端,大幅縮減了 JavaScript 包體積。
  • 安全性高:敏感的資料庫密碼、API 金鑰或內部驗證邏輯可以安全地放在伺服器端執行,外洩風險趨近於零。

二、Client Components

當元件需要依賴瀏覽器專屬環境或動態狀態時,必須在檔案最頂端加上 "use client" 指令。這並非代表該元件「只能在瀏覽器渲染」,而是建立了一個「模組邊界(Boundary)」。

  • 何時必須使用 "use client"
    • 狀態與生命週期useStateuseEffectuseReduceruseTransition
    • 使用者互動事件onClickonChangeonSubmit 等。
    • 瀏覽器原生 APIwindowdocumentlocalStoragenavigator
    • 自訂 Hook:任何內部調用了上述 Hooks 的自訂 Hook。
  • 打包傳遞:被標記為 "use client" 的元件及其引用的所有子元件,都會被打包並下載到瀏覽器中執行(SSR 初始化後進行 Hydration 水合)。

三、父抓資料、子做互動

實務開發中最有效率的設計模式,是讓 Server Component 擔任父層,而 Client Component 擔任子層

  1. 父層 (Server Component):負責初始化、向資料庫抓取資料(例如 await listItems()),並將靜態資料透過 Props 往下傳遞。這確保了首屏載入時,資料已經內嵌在 HTML 中,對 SEO 極度友善。
  2. 子層 (Client Component):接收資料後,負責處理複雜的 UI 互動、狀態切換(如前面實作的 ItemCard 裡的勾選、刪除、useTransition 載入狀態)。

這種設計兼顧了 Server-side 的極速載入Client-side 的豐富互動,是現代全端框架的最佳實踐。


四、RSC Payload 與傳輸協定

當伺服器收到網頁請求時,Server Component 並不會直接轉成普通的 HTML 字串,而是會被編譯並序列化成一種稱為 RSC Payload 的特殊資料結構。其包含:
1. 伺服器端元件執行後的渲染結果
2. 預留給 Client Component(例如 ItemCard)的佔位符(Slots)與對應的 JS 檔案參照路徑。
3. 由 Server 端傳遞給 Client 端的 Props 資料(例如從資料庫撈出來的 item 物件)。

瀏覽器首次載入時,伺服器會結合 HTML 與 RSC Payload 一起送達。瀏覽器收到後,會用 HTML 快速拼出首屏畫面,然後利用 RSC Payload 在背景將 Client Component「水合(Hydration)」並點亮互動功能。


Hydration

當使用者輸入網址,伺服器只是把排版好的 HTML 傳給瀏覽器。使用者雖然瞬間就能看到畫面(First Contentful Paint 很高),但這只是一張「沒有靈魂的精美海報」,你點擊按鈕、輸入框,完全沒反應,因為 JavaScript 還沒執行。

而 Hydration 就像是把脫水食品加水還原,當瀏覽器接著下載 JavaScript 檔案時,React 會把對應的事件監聽器(如 onClick、useState 等狀態)重新綁定到對應的 DOM 元素上。

這個「把事件和狀態綁上去」的過程,就是 Hydration。完成之後,網頁就從「靜態圖片」變成「真正的互動應用」了。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言