跳到主要內容

發表文章

目前顯示的是 3月, 2026的文章

FE Day 19 Server Components 與資料取得

FE Day 19 Server Components 與資料取得 執行需求:CPU 可跑 。今天是「前端開發實戰:React 與 Next.js 全套」系列的第十九篇,我們把 App Router 最重要的觀念攤開來看——Server Component 怎麼拿資料、為什麼要這樣設計、四種快取策略怎麼選、以及怎麼把真實的 HTTP 呼叫收進一個好維護的資料層。延續前兩天蓋好的 booking-fe 專案,我們會把 fetch 包進 src/lib/api.ts 、把「拿單筆預約」「拿預約清單」「拿使用者 session」三個動作變成可組合的函式,並讓 page.tsx 直接 await。整篇範例不依賴真實後端,本機用 mock 資料就能跑,串接 Web 系列的 FastAPI 只要換 base URL。 引言 前端工程師剛接觸 Next.js 的 Server Component 時,最常問的問題是:「這不就是回到 SSR 了嗎?」答案接近「對,但不只是 SSR」。SSR(Server-Side Rendering,伺服器端渲染)在 React 的脈絡裡指的是「在伺服器上把 HTML 產出來,再送到瀏覽器」。Server Component 更進一步: 元件本身在伺服器上執行,連 JavaScript bundle 都不送給瀏覽器 。這意味著兩件事——伺服器可以直接讀資料庫、打後端 API、讀環境變數、讀檔案系統;瀏覽器只收到渲染好的 HTML 與極少量的互動程式碼。 這個模型對「後端工程師」其實非常友善:你寫 React 元件的方式跟在後端寫函式差不多,可以直接 await 、可以直接拿環境變數、不需要寫 Redux 或 React Query。Next.js 在 build time 自動把 Server Component 與 Client Component 拆成兩個 bundle,伺服器 bundle 永遠不會送到瀏覽器,client bundle 也不會被伺服器執行。兩邊的邊界由 "use client" 標記決定,沒寫的就是 Server Component。 今天的目標有四個:第一,把 Server Component 的「為什麼」講清楚,包含它對 bundle size 與資料來源的影響;第二,建立...

FE Day 18 路由:巢狀、動態與載入狀態

FE Day 18 路由:巢狀、動態與載入狀態 執行需求:CPU 可跑 。今天是「前端開發實戰:React 與 Next.js 全套」系列的第十八篇。昨天我們把 Next.js 15 App Router 起步了,知道了 Server/Client Component 的邊界、五個約定檔的位置。今天要進入路由設計的精華:「檔案系統即路由」怎麼表達巢狀、動態參數、載入狀態,以及「route group(路由群組)」怎麼在不改變網址的前提下切換 layout。我們會在 booking-fe 上加 /bookings 、 /bookings/[id] 、 /bookings/[id]/edit 、 /bookings/new 四條路由,並示範「側邊欄 layout + 內容區 page」的標準巢狀結構。讀完之後你應該能在 30 秒內決定任何一段新路由的檔案該放哪。 引言 寫後端的工程師對「URL 即資源」非常熟悉—— GET /users/42/orders 表示「使用者 42 的所有訂單」。這個觀念跟 App Router 的檔案系統完全對應: app/users/[id]/orders/page.tsx 就是 /users/42/orders 。資料夾是 URL 區段、檔案是端點、約定檔決定它扮演什麼角色。比起 Pages Router 的「全部路由寫進 pages/ 」、React Router 的「全部路由寫進一支設定檔」,App Router 的設計更接近後端的「目錄即資源」直覺。 今天重點放在三件事。第一,巢狀路由(nested routes)——資料夾一層一層對應到 URL 一層一層, layout.tsx 在每一層自動包下層,這是後端「共用 layout」最乾淨的寫法。第二,動態路由(dynamic routes)—— [id] 、 [...slug] 、 [[...slug]] 三種括號的差別,以及 generateStaticParams 怎麼決定哪些動態值要預先建好。第三,載入與錯誤狀態—— loading.tsx 、 error.tsx 、 not-found.tsx 放在「對應的目錄下」就只影響那一段路由,不會打擾其他頁面。我們也會順道提 route group(用 (name) 命名的資料夾)這個「不影響 UR...

FE Day 17 Next.js 起步:App Router 與檔案結構

FE Day 17 Next.js 起步:App Router 與檔案結構 執行需求:CPU 可跑 。今天正式進入 Next.js 篇章。前面十六篇你用純 React 加 Vite 學會了元件、狀態、Hook、樣式、測試、專案結構,這些觀念在 Next.js 完全沿用;多出來的是「框架接管了路由、打包、開發伺服器、部署介面」。從今天起,往後四篇會把焦點放在 App Router:怎麼用檔案系統定義路由、怎麼區分 Server Component 與 Client Component、怎麼用四個約定檔( layout.tsx 、 page.tsx 、 loading.tsx 、 error.tsx )把畫面包起來。我們一步步把昨天的純 React 專案搬進 Next.js 15,跑得起來再談細節。 引言 很多後端工程師第一次碰到 Next.js 會被兩個東西嚇到:第一個是「App Router 跟舊的 Pages Router 差很多」,第二個是「Server Component 跟我熟悉的 React 不一樣」。Pages Router 是 2016 年發布的版本( pages/ 底下每支 .tsx 就是一個路由,元件預設是 Client Component,用 getServerSideProps 或 getStaticProps 處理 SSR),App Router 是 2023 年發布的版本( app/ 底下用 page.tsx 、 layout.tsx 等約定檔,元件預設是 Server Component,用 "use client" 切到 Client)。這個系列從 Day 17 起「只談 App Router」,舊的 Pages Router 不再展開。為什麼?因為官方在 Next.js 13 之後就把 App Router 設為預設,Pages Router 雖然還能跑,但新教學、新範例、新工具鏈都圍繞 App Router 設計。 本篇會做七件事:第一,說明 App Router 的「檔案系統即路由」觀念;第二,解釋 Server Component 與 Client Component 的邊界;第三,示範 create-next-app 建立專案;第四,把根目錄的 layout.tsx 、 pa...

FE Day 15 測試:Vitest 與元件測試

FE Day 15 測試:Vitest 與元件測試 執行需求:CPU 可跑 。今天是系列的第十五篇。前十四天我們從環境、TypeScript、React 元件、Hooks、Context、表單到 TanStack Query 一路往上疊,寫了不少「能跑」的程式碼。但程式碼能跑跟「改完不會壞掉」是兩件事——後者需要測試。今天要介紹前端測試的事實標準——Vitest 3.x 與 React Testing Library,把前幾天寫的 Hook、表單、API 呼叫全部加上單元測試。我們會從最基本的「斷言一個數字」開始,逐步演練到「測試自訂 Hook」、「測試表單送出」、「測試 TanStack Query 元件」、「mock fetch」。整篇範例都在本機 CPU 跑得起來,不依賴雲端服務,跑完你會拿到一份可以直接 pnpm test 跑的測試套件。 引言 寫後端的我們對測試並不陌生:pytest、unittest、fixture、mock、coverage——這些是後端的基本功。前端的測試觀念類似,但工具有差異:Vitest 是「Vite 生態的測試執行器」,速度比 Jest 快很多、與 Vite 設定共用;React Testing Library(RTL)是「以使用者觀點測試元件」的函式庫,鼓勵你測「使用者會做什麼」而不是「元件內部狀態」。兩者結合起來就是 React 專案最常見的測試組合。 前端測試的價值不只是「驗證邏輯正確」,更重要的是「讓改 code 變得安全」。當元件長大、邏輯變複雜,一個小修改可能影響到整個應用。有測試的話,改壞了 CI 會跳出來擋下;沒測試的話,使用者會跳出來擋你。前端測試還有一個獨特價值:能在「不啟動瀏覽器」的情況下驗證元件,這對 CI 環境特別有用。 今天要回答五個問題:第一,Vitest 3.x 怎麼設定?第二,怎麼用 React Testing Library 測元件?第三,怎麼用 renderHook 測自訂 Hook?第四,怎麼 mock fetch 與 localStorage?第五,怎麼測 TanStack Query 元件?我們會給 useToggle、useDebounce、BookingForm、BookingList 寫完整測試。整篇閱讀時間約 35 分鐘,動手做大約 45 分鐘。 安裝...

FE Day 16 專案結構與程式碼組織

FE Day 16 專案結構與程式碼組織 執行需求:CPU 可跑 。今天是「前端開發實戰:React 與 Next.js 全套」系列的第十六篇。前十五天你學會了元件、狀態、Hook、樣式、測試,這些東西散落在幾個檔案時還能跑;專案長大到幾十個元件、數百個檔案時,沒有結構的程式會變得「找檔案比寫程式還累」。今天把後端工程師熟悉的「分層」思惟搬到 React 上,建立一套可以撐到數百個檔案也穩定的資料夾結構,並把路徑別名、Lint 規則、共用型別、Barrel Export 的取捨一次講清楚。整篇的範例都在本機 CPU 跑得起來,不依賴任何雲端服務。 引言 寫後端的工程師對「分層」一點都不陌生:route 層、service 層、repository 層、model 層,每層的職責清楚,跨層呼叫的方向固定,CI 跑測試時可以一層一層驗證。React 專案長大之後也需要類似的分層,新手最常把所有東西塞進 src/components/ ,結果一個資料夾裡同時混著 Button、useBooking、formatDate、api.ts,找檔案變成「捲動加猜測」,新成員 onboarding 變成考古。 本系列從 Day 5 開始的範例都是「小到能放在一個檔案」的程度,結構問題不明顯。但預約管理系統從 Day 31 開始要長到數十個元件、上百個檔案,如果現在不把骨架蓋好,後面每一天都會被「這段程式該放哪」這個問題打斷。今天的目標是把一個小型 React 專案重構成「以角色為主」的分層結構,讓檔案位置能反映程式碼的職責,並說明怎麼用 Lint 把不一致擋在 PR 階段。 版本基準延續前幾天:Node.js 22 LTS/24 LTS、TypeScript 5.9、React 19.x、Vite 7、Vitest 3.x、ESLint 9 flat config;明天 Day 17 才會切到 Next.js 15/16 的 App Router,所以今天的結構以「純 React 加 Vite」為主,但分層觀念完全通用,搬到 Next.js 也直接適用。讀完之後你應該能在 30 秒內決定任何一段新程式碼該放哪個資料夾,並且能用 Lint 把違反結構的程式碼擋下。 為什麼「全部塞進 components」會爆炸 新手最常見的起手式是「在 src/compo...

FE Day 14 資料取得與前端快取

FE Day 14 資料取得與前端快取 執行需求:CPU 可跑 。今天是系列的第十四篇(註:原 SPEC 將資料取得排在 Day 14,本篇按 manifest-fe.json 標題為「FE Day 14 資料取得與前端快取」編寫)。前幾天我們用 useEffect、useState、自訂 Hook 與 Context 寫過一些 useFetch 範例,那些寫法能用但不夠好——當元件樹長大、需要管理「載入中」、「錯誤」、「快取」、「重試」、「競態」等多個維度時,純手寫的程式碼很快就會失控。今天要介紹前端資料取得的事實標準——TanStack Query(舊稱 React Query),它把以上所有維度包成一個輕量函式庫,讓你用幾行程式碼就能做到「自動重試、快取 5 分鐘、分頁與重新取得、樂觀更新、錯誤處理」。我們會把昨天的 useFetch 改寫成 TanStack Query 版本,並用它做一個完整的「預約清單 + 篩選 + 新增 + 刪除」流程。整篇範例都在本機 CPU 跑得起來,需要一個本機的 mock API(會附上完整的 mock 伺服器範例)。 引言 寫後端的時候,「資料取得」就是發個 HTTP 請求。前端的「資料取得」聽起來也一樣——呼叫 fetch 或 axios 拿資料、回傳給元件渲染。但實務上前端的資料取得要處理的事情遠多於「打一次 API」:使用者切換分頁要不要重新打?同一份資料兩個元件都要用,要不要共用?API 失敗要不要自動重試?使用者按「重新整理」要怎麼處理?當使用者修改資料時,UI 要「樂觀更新」還是「等 API 回來才更新」? 這些問題的答案在純手寫的 useEffect + useState 裡都會變成「每個專案各寫一套」。TanStack Query 把這套邏輯收斂成一個函式庫,提供一致的 API 處理快取、錯誤、重試、競態、stale 狀態等問題。它不是「另一個 fetch 套件」,而是「前端資料層」——把你從「自己管理快取」解放出來,專注在「資料怎麼用」。 今天要回答五個問題:第一,前端資料取得有哪些痛點?第二,TanStack Query 的核心 API 是什麼?第三,怎麼用它實作「預約清單」與「預約新增」?第四,快取策略(staleTime、gcTime、invalidate)怎麼設定?第五,怎麼處...