第九章:拯救你的表單地獄 - React Hook Form 與 Zod 的終極防禦

在任何一個管理後台系統中,除了顯示資料的表格 (Table) 之外,最常做的事情就是讓使用者填寫表單 (Form)。例如:「新增員工資料」、「修改打卡時間」、「設定系統參數」。

如果你曾經自己用傳統的 React useState 來寫表單,你一定經歷過這場惡夢: 你要為每個輸入框寫一個 onChange 函數,你要手動檢查「這個 Email 有沒有打錯?這個密碼是不是大於 8 碼?」如果使用者打錯了,你還要手動設定紅色的錯誤訊息,然後在畫面重新渲染。如果表單有 10 個欄位,你的程式碼會輕易突破 300 行,而且每次打字都會導致整個畫面卡頓 (因為一直觸發重新渲染)。

這就是為什麼業界開發出了表單的終極武器組合。

🎯 本章目標

  1. 認識業界效能最強、最輕量的表單管理套件:React Hook Form (RHF)
  2. 認識讓前端工程師不再頭痛的資料驗證 (Schema Validation) 套件:Zod
  3. 讓 AI 幫我們把這兩者完美結合,寫出一個防呆做到極致、效能極佳的「新增員工表單」。

🛡️ 什麼是 React Hook Form 與 Zod?

  • React Hook Form:負責管理表單的狀態。它的特色是採用「非受控元件 (Uncontrolled Components)」的技術,這意味著你在打字時,網頁不會每打一個字就重新渲染,效能好到無可挑惕。
  • Zod:負責定義「規則」。你可以用非常像白話文的語法告訴 Zod:「我規定姓名必須是字串,且長度最少 2 個字;信箱必須符合標準 Email 格式。」Zod 就像一個嚴格的警衛,只有全部符合規則的資料,才能通過它的審查。

🔥【Vibe Prompt 實戰咒語】 我正在開發 React 專案。我需要做一個「新增員工」的精美表單。 1. 請給我 npm 安裝 react-hook-form, zod, 以及 @hookform/resolvers 的指令。 2. 請在元件中定義一個 Zod Schema,包含防呆錯誤訊息: - name (字串,必填,最少 2 個字,否則提示 "名字太短") - email (字串,必須是合法的 Email,否則提示 "信箱格式錯誤") - department (下拉選單,選項為 "工程部" 或 "行銷部") 3. 請使用 useForm 與 zodResolver 將表單綁定在一起。 4. UI 請使用 Tailwind CSS,要有圓角、陰影,並垂直排列 (space-y)。 5. 如果使用者亂填就按送出,請在該 Input 欄位的正下方,顯示紅色的錯誤訊息文字。

AI 會教你安裝這些黃金組合:

npm install react-hook-form zod @hookform/resolvers

並且生成極度優雅且防護嚴密的元件程式碼:

// 📂 src/components/EmployeeForm.tsx
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";

// 1. 定義嚴格的防呆規則 (Schema) 與報錯文字
const employeeSchema = z.object({
  name: z.string().min(2, { message: "名字至少要 2 個字喔!" }),
  email: z.string().email({ message: "這看起來不像信箱格式喔!" }),
  department: z.enum(["工程部", "行銷部"], {
    errorMap: () => ({ message: "請選擇一個部門" })
  }),
});

// 使用 TypeScript 自動從 Zod 規則推導出型別 (超方便!)
type EmployeeFormValues = z.infer<typeof employeeSchema>;

export default function EmployeeForm() {
  // 2. 啟動 React Hook Form,並請 Zod 警衛來把關
  const { 
    register,     // 用來把 Input 註冊給 RHF 管
    handleSubmit, // 用來攔截原本的 form 送出事件
    formState: { errors } // 這裡面裝著所有即時的錯誤訊息
  } = useForm<EmployeeFormValues>({
    resolver: zodResolver(employeeSchema),
  });

  // 3. 只有當資料 100% 符合規則時,才會進到這個函數!
  const onSubmit = (data: EmployeeFormValues) => {
    console.log("成功送出,準備打 API:", data);
    alert(`新增成功:${data.name}`);
  };

  return (
    <div className="max-w-md mx-auto bg-white p-8 rounded-2xl shadow-sm border border-slate-100">
      <h2 className="text-xl font-bold mb-6 text-slate-800">新增員工資料</h2>
      
      <form onSubmit={handleSubmit(onSubmit)} className="space-y-5">
        {/* 姓名欄位 */}
        <div>
          <label className="block text-sm font-medium text-slate-700 mb-1">姓名</label>
          <input 
            {...register("name")} 
            className="w-full border border-slate-300 rounded-lg p-2 focus:ring-2 focus:ring-blue-500 outline-none"
            placeholder="請輸入真實姓名"
          />
          {/* 錯誤顯示區塊:只有出錯時才會顯示紅字 */}
          {errors.name && <p className="text-red-500 text-sm mt-1">{errors.name.message}</p>}
        </div>
        
        {/* Email 欄位 */}
        <div>
          <label className="block text-sm font-medium text-slate-700 mb-1">電子信箱</label>
          <input 
            {...register("email")} 
            className="w-full border border-slate-300 rounded-lg p-2 focus:ring-2 focus:ring-blue-500 outline-none"
            placeholder="example@company.com"
          />
          {errors.email && <p className="text-red-500 text-sm mt-1">{errors.email.message}</p>}
        </div>

        {/* 提交按鈕 */}
        <button 
          type="submit" 
          className="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-lg transition-colors"
        >
          儲存資料
        </button>
      </form>
    </div>
  );
}

💼 [商業應用場景] 為什麼前端的防呆這麼重要?

如果你不加 Zod 防呆,讓使用者亂填了一堆空白的名字、或是根本沒有 @ 的信箱,這筆爛資料就會送到後端 (FastAPI)。 後端當然也會檢查,然後後端會報錯,把錯誤訊息傳回前端,前端再顯示出來。 這個過程叫做「伺服器端驗證 (Server-side Validation)」。它浪費了網路傳輸的時間,也浪費了伺服器的算力。

一個專業的軟體公司,會做到「前後端雙重驗證」。 前端利用 Zod,在使用者根本還沒發出 API 之前,就在他的瀏覽器端用極快的速度把他擋下來,告訴他「你信箱打錯了喔」。這不僅節省了伺服器成本,還能給使用者「即時的回饋感」,這就是你系統好用、客戶願意續約的關鍵秘密!

✅ 本章小結

這套 React Hook Form + Zod 的黃金組合,已經是目前全端開發的「終極答案」。 它徹底改變了過去前端寫表單的痛苦生態。學會這招,未來不管是面對幾十個欄位的「進階過濾器」,還是多重步驟的「結帳問卷系統」,你都能像切豆腐一樣輕鬆秒殺!

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!