beio Logobeio

【App 工程師的前端轉生術 02】觀念重塑:Next.js Runtime 與 App 生命週期

發布於

01. 前言:我的 AppDelegate 去哪了?

搞定了 VS Code 環境後,你滿懷信心地打開 Next.js 專案,準備找程式的入口點(Entry Point)。

  • iOS: 你會找 AppDelegate@main 的 App Struct。
  • Android: 你會找 AndroidManifest.xml 定義的 Main Activity。
  • Next.js: 你打開 src/app,只看到一堆資料夾和 page.tsxlayout.tsx

你心中浮現第一個問號:「誰負責初始化我的 App?全域變數要放哪?Navigation Stack 又是怎麼管理的?」

這篇文章不寫太多程式碼,而是要進行一場**「心智模型遷移」**。我們要將你腦中根深蒂固的 Mobile 架構圖,映射到 Next.js 的 App Router 架構上。

02. 框架定位:Next.js 是你的 OS,React 只是 UI Kit

首先要釐清一個誤區。很多 App 工程師以為前端開發就是「寫 React」。

精準的類比是:

  • Next.js $\approx$ iOS SDK / Android SDK:它負責編譯、路由、生命週期、資源載入。
  • React $\approx$ SwiftUI / Jetpack Compose:它只是一個 Library,負責「將狀態轉換為 UI」。

你不能單純只學 React,就像你不能只學 SwiftUI 但不懂 iOS App LifeCycle 一樣。

03. 路由系統:資料夾就是你的 Navigation Graph

在 App 開發中,Navigation 是一件大事。

  • iOS: UINavigationController.pushViewController(...)
  • Android: startActivity(Intent) 或 Jetpack Navigation Graph XML。

Next.js 使用 File-system based Routing。你不必手動註冊路由,資料夾結構即路由

結構對照表

Next.js 檔案App 對應概念職責
app/layout.tsxWindowGroup / MainActivity全域容器。負責 <html lang="en">、字體載入、全域 Provider (Theme, Context)。它不會因為頁面切換而銷毀(Re-mount)。
app/dashboard/layout.tsxTabBarController / NavigationDrawer子模組容器。例如 Dashboard 裡面有側邊欄,切換子頁面時側邊欄不動。
app/dashboard/page.tsxDashboardViewController / DashboardFragment頁面實體。這是路由的終點,負責渲染該頁面的特定內容。
app/loading.tsxActivityIndicator / Skeleton View系統級 Loading。當路由正在切換(Transition)時,框架自動顯示的佔位 UI。
app/not-found.tsxFallback UI處理 404 錯誤,類似 App 的錯誤空狀態頁。

🧠 Mobile 思維模擬

當使用者從 / 點擊連結到 /dashboard 時:

  1. Next.js: 保持根目錄的 layout.tsx 不變,卸載首頁的 page.tsx,掛載 /dashboard/page.tsx
  2. iOS: NavigationController (Layout) 保持不動,Pop 掉舊 VC,Push 進新 VC。

這完全就是一個 Native App 的 Navigation Stack 行為!

04. 渲染模式:Server Component 的震撼

這是 App 工程師最難理解的部分。 Mobile App 是 100% Client-side Rendering (CSR),所有程式碼都打包在 IPA/APK 裡,在手機 CPU 上執行。

Next.js 預設使用 React Server Components (RSC)

什麼是 Server Component?

想像一下 Server-Driven UI (SDUI),但是原生支援。

  • 這個 Component 的程式碼 只在伺服器上執行
  • 它可以直接讀資料庫、讀檔案系統。
  • 不會 被打包進送往瀏覽器的 JavaScript Bundle(縮小 App 體積)。
  • 它產出的是 HTML (或是類似 JSON 的中介格式),瀏覽器只負責顯示。

什麼是 Client Component ("use client")?

這才是你熟悉的 Standard React / Mobile View

  • 在瀏覽器(手機)上執行。
  • 可以使用 useState (狀態)、useEffect (生命週期)、onClick (互動)。

決策樹:我該用哪種?

  • 需要讀資料嗎? $\rightarrow$ Server Component (在後端直接拿,不用過 API)。
  • 需要 onClickonChange 嗎? $\rightarrow$ Client Component。
  • 需要瀏覽器 API (window, localStorage) 嗎? $\rightarrow$ Client Component。

這就像是你的 App 架構中,把 Data Fetching & Formatting 全部移到後端做掉,手機只拿到算好的 UI 結構來渲染,效能極高。

05. 生命週期:Hydration (水合) 是什麼鬼?

Mobile App 啟動過程:

  1. Cold Start: 載入 Binary。
  2. Launch Screen: 顯示靜態圖。
  3. Application onCreate: 初始化邏輯。
  4. Interactive: 使用者可以點擊。

Next.js (Web) 的啟動過程:

  1. HTML Load: 瀏覽器下載 HTML (由 Server Component 預先生成)。
  2. Paint: 使用者看到畫面了!(對應 Launch Screen,但內容是真實的)。
  3. Hydration: 下載 JavaScript,React 在背景執行,把事件監聽器 (Event Listeners) 綁定到現有的 HTML 上。
  4. Interactive: 畫面「活」過來了,按鈕可以點了。

⚠️ 常見的坑:Hydration Mismatch

這對應到 App 的 UI Glitch。 如果你在 Component 裡寫:

// ❌ 錯誤示範
const isMobile = window.innerWidth < 768; 
  • Server 端: 沒有 window,渲染出 A 樣式。
  • Client 端: 有 window,渲染出 B 樣式。
  • 結果: React 發現兩邊 HTML 對不上,報錯 Hydration failed,畫面閃爍。

解決方案:確保初始渲染(Initial Render)在 Server 和 Client 是一致的,把依賴 Browser API 的邏輯放在 useEffect (Client Only) 中。

06. 小結:你是在寫一個「分散式 App」

讀完這篇,你應該對 Next.js 有了新的認知:

  1. Next.js 專案 $\approx$ 一個部分邏輯跑在 Server (RSC),部分跑在手機 (Client) 的混合 App。
  2. App Router $\approx$ 你的 Navigation Controller。
  3. Layout $\approx$ 你的 Activity/WindowGroup。

有了這個心智模型,你就不會再被那些「為什麼這裡不能用 useState?」(因為它是 Server Component) 或者「為什麼找不到 index.html?」(因為它是動態生成的) 的問題卡住了。

在下一篇 Part 3,我們將進入程式碼實戰,解決 App 工程師最害怕的「弱型別恐懼症」,引入 ZodRepository Pattern 來打造原生級的資料層防護網。


Ken Huang

關於作者

Ken Huang

熱衷於嘗試各類新技術的軟體開發者,現階段主力為 Android / iOS 雙平台開發,同時持續深耕前端與後端技術,以成為全端工程師與軟體架構師為目標。

最廣為人知的代表作為 BePTT。開發哲學是「以做身體健康為前提」,致力於在工作與生活平衡的基礎上,打造出擁有絕佳使用體驗的軟體服務。

這裡是用於紀錄與分享開發經驗的空間,希望能透過我的實戰筆記,幫助開發者解決疑難雜症並提升效率。

Android APP DevelopmentiOS APP DevelopmentBePTT CreatorFull Stack Learner