第 13 週 · 單元 5-1 · 換一套技術
Next.js(下):表單、測試、上線,以及兩種技術的比較
用 Server Action 完成新增評論與新增店家,部署到 Vercel,最後寫一份兩種技術的比較,作為期末專題選擇技術的依據。
W13Next.js表單+上線
本週結束時你會
今天的時間安排
| 0:00–0:45 | 功能 3【跟著做】新增評論(Server Action+useActionState) |
| 0:45–1:10 | 功能 4【自己做】新增店家 |
| 1:10–1:20 | 休息 |
| 1:20–1:45 | 驗收:單元測試與手動測試 |
| 1:45–2:10 | 上線:Vercel 匯入、設定 DATABASE_URL |
| 2:10–2:30 | 兩種技術比較、專案回顧 |
功能 3:新增評論【跟著做】
提示詞 Antigravity
請先讀 PROJECT.md。現在只做「新增評論」: 1. 把表單規則寫成 lib/validate.js 裡的純函式 validateReview(不碰資料庫),規則和 Flask 版完全相同:暱稱必填且最多 20 字、評分 1–5 的整數、短評最多 100 字 2. 在 lib/actions.js 寫 Server Action addReview:先呼叫 validateReview;有錯誤時回傳錯誤與使用者已輸入的內容;成功時用 $1 參數寫入資料庫、revalidatePath,再 redirect 回店家頁 3. 評論表單做成 Client Component,用 React 的 useActionState 顯示錯誤並保留已輸入的內容,送出中時按鈕停用 4. 用 Node.js 內建的 node:test 為 validateReview 寫單元測試,npm test 可以執行 只修改和這條功能相關的檔案。
| 輸入(在 /shop/1) | 正確結果(與第 5 週相同) |
|---|---|
| 測試員、5 星 | ★ 4.7(7 則評論),第一則是測試員 |
| 用開發者工具把選項改成 6 送出 | 「評分必須是 1 到 5 的整數」,短評內容仍保留 |
| 暱稱空白、短評 101 字 | 分別顯示對應的錯誤 |
為什麼要把規則抽成純函式:不碰資料庫的函式很好測試,執行一次不到一秒。Flask 版用 test_client 測整個網站;Next.js 版先把最容易出錯的規則用單元測試鎖住,網頁的部分再手動測試。
用開發者工具竄改選項時要注意:送出失敗後 React 會重新繪製表單,但被竄改過的 option 不一定會被還原。測試正確輸入前,請先重新整理頁面,否則看起來像「正確的評分也被擋下」。這是製作參考解答時實際遇到的狀況。
功能 4:新增店家【自己做】
| 輸入 | 正確結果 |
|---|---|
| 測試咖哩、飯 | 導向新店家頁,排行榜最後多一間尚無評分 |
| 派森牛肉湯、小吃 | 「這家店已經在名單中了」 |
| 類別改成「火鍋」送出 | 「請選擇類別」 |
測試完執行 npm run init-db 讓資料回到 12 間店、49 則評論。
上線:Next.js 部署到 Vercel
- 對 Antigravity 說「推上 GitHub。儲存庫名稱 foodie-next,Public。」,確認 .env.local 沒有被推上去。
- Vercel 匯入 foodie-next,Framework 會自動偵測為 Next.js。
- 到 Storage 把同一個 Neon 資料庫連到這個專案(Vercel 會設定 DATABASE_URL,預設使用 main 分支)。
- 在 Neon 的 SQL Editor 執行 db/schema.sql 與 db/seed.sql,然後重新部署。
應該看到Next.js 版的公開網址,排行榜與 Flask 版完全相同。
兩種技術比較
在 PROJECT.md 最後加一段「技術比較」,用你這兩個月的實際經驗填寫,期末專題選技術時會用到:
| 比較項目 | Flask | Next.js |
|---|---|---|
| 同一條功能,誰的程式比較短? | ||
| 出錯時,哪一個的錯誤訊息比較好懂? | ||
| 測試好不好寫? | ||
| 部署難度 | ||
| AI 寫得比較穩的是哪一個?舉一個例子 | ||
| 期末專題我會選擇,原因是 | ||
沒有標準答案。常見的觀察:Flask 的資料流比較直觀,適合以表單與資料表為主的網站;Next.js 適合畫面互動多、需要即時更新的網站,但多了伺服器與瀏覽器之間的界線要理解。鼓勵學生依期末題目的性質選擇,而不是依喜好。
本週檢核
驗證紀錄:Next.js 參考解答(Next.js 15.5、React 19、Node.js 22)通過 10 項單元測試;排行榜、類別篩選、404、新增評論、竄改評分、重複店家,都已在瀏覽器實際操作並與 Flask 版的標準答案比對一致。