---
# System prepended metadata

title: "\U0001F3C5Day42 - React 套件應用 (8) - Reack-Hook-Form"
tags: [React 直播班 - 2024 冬季班]

---

React Hook Form 是 React 領域中功能強大且高效的表單處理工具。它的輕量性、簡單性和高度靈活性，使其成為構建現代表單的首選解決方案。開發者可以快速構建高性能、可擴展的表單應用。

### 與其他工具的比較
![image](https://hackmd.io/_uploads/ryIMB-qf1l.png)

### 核心功能與概念
useForm 是 React Hook Form 的主要 Hook，提供表單管理的基礎功能，包括註冊輸入字段、處理表單提交、收集驗證錯誤等。

```js
const { register, handleSubmit, formState } = useForm();
```
1. register: 綁定到輸入框以追蹤其值和驗證狀態。
2. handleSubmit: 包裹提交事件處理函數，執行驗證並調用成功回調。
3. formState: 表單的狀態（例如錯誤、是否已修改等）。
4. reset: 重置表單數據到初始值。
5. setValue: 手動設置表單字段的值。

register 將輸入框註冊到 React Hook Form 的狀態管理中，同時綁定驗證規則。

```js
<input
  {...register("email", {
    required: "電子郵件是必填項目",
    pattern: {
      value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/,
      message: "請輸入有效的電子郵件",
    },
  })}
/>
```
RHF 支持內建的驗證功能：
1. required: 必填字段。
2. minLength 和 maxLength: 長度限制。
3. pattern: 正則表達式匹配。
4. validate: 自定義驗證函數。
```
<input
  {...register("password", {
    required: "密碼是必填項目",
    minLength: {
      value: 6,
      message: "密碼長度至少為 6 個字元",
    },
    validate: (value) =>
      value.includes("!") || "密碼必須包含驚嘆號 (!)",
  })}
/>
```
另外 errors 是 formState 中的一部分，用於存儲驗證錯誤信息。
```
{errors.email && <p>{errors.email.message}</p>}
```
使用 reset 方法重置表單到初始狀態。
```js
const { reset } = useForm();
reset({
  email: "",
  password: "",
});
```

## 題目
請複製 （右下角 fork）這個[範例](https://codepen.io/yen-kg/pen/gOVJKvG?editors=1010)，完成以下條件：

1. 在點擊提交時加入欄位驗證，並將錯誤訊息顯示出來 ( 如下圖 )。若成功提交後，將表單的所有欄位清空。
2. 使用者名稱、電子郵件、密碼都為必填，電子郵件需要符合 email 格式、密碼最少要六位數。

![image](https://hackmd.io/_uploads/Bk3Jfz5Gyl.png)

## 回報流程
將答案寫在 CodePen 並複製 CodePen 連結貼至底下回報就算完成了喔!
解答位置請參考下圖（需打開程式碼的部分觀看）
![](https://i.imgur.com/vftL5i0.png)

<!-- 解答： 
```
const { useForm } = ReactHookForm;

const App = () => {
  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm(); // 使用 useForm

  const onSubmit = (data) => {
    reset();
  };

  return (
    <div className="container mt-5">
      <h2 className="text-center mb-4">註冊表單</h2>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div className="mb-3">
          <label htmlFor="username" className="form-label">使用者名稱</label>
          <input
            id="username"
            type="text"
            className="form-control"
            placeholder="輸入使用者名稱"
            {...register("username", { required: "使用者名稱是必填的" })}
          />
          {errors.username && <div className="text-danger">{errors.username.message}</div>}
        </div>

        <div className="mb-3">
          <label htmlFor="email" className="form-label">電子郵件</label>
          <input
            id="email"
            type="email"
            className="form-control"
            placeholder="輸入電子郵件"
            {...register("email", {
              required: "電子郵件是必填的",
              pattern: {
                value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
                message: "請輸入有效的電子郵件地址",
              },
            })}
          />
          {errors.email && <div className="text-danger">{errors.email.message}</div>}
        </div>

        <div className="mb-3">
          <label htmlFor="password" className="form-label">密碼</label>
          <input
            id="password"
            type="password"
            className="form-control"
            placeholder="輸入密碼"
            {...register("password", {
              required: "密碼是必填的",
              minLength: {
                value: 6,
                message: "密碼長度必須至少為 6 個字元",
              },
            })}
          />
          {errors.password && <div className="text-danger">{errors.password.message}</div>}
        </div>

        <button type="submit" className="btn btn-primary w-100">提交</button>
      </form>
    </div>
  );
};

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
```
-->


回報區
---


| # | Discord  |                         CodePen / 答案                          |
| 1 | 4chan |[Codepen](https://codepen.io/ijuolaqc-the-looper/pen/ZYEbMjW)|
|:-:|:-------:|:---------------------------------------------------------------:|
| 2 | Nocab |[Codepen](https://codepen.io/PeihanWang/pen/KwKdxzL?editors=1011)|
| 3 | Aaron 謝宗佑 |[Codepen](https://codepen.io/aaron-hsieh/pen/PwoPdvg)|
| 4 | Noy(Toad) | [Codepen](https://codepen.io/MochiCodingPen/pen/gbOaQzR) |
|5|Hailey|[CodePen](https://codepen.io/sxbokfja-the-flexboxer/pen/jEObdmM?editors=1011)|
|6|Kaya|[CodePen](https://codepen.io/kayaribi/pen/ByaoMxj)|
| 7 | 毛巾 |[CodePen](https://codepen.io/bqdcjboa-the-solid/pen/NPWGEQL)|
| 8 | 泊岸 |[CodePen](https://codepen.io/qoq77416416/pen/OPJMrrB?editors=0011)|
| 9 | 嚼勁先生 |[CodePen](https://codepen.io/James520284/pen/gbOPNEm)|
| 10 | Johnson |[CodePen](https://codepen.io/crpbugqy-the-typescripter/pen/xbxOqOv)|
| 11 | Rogan |[CodePen](https://codepen.io/RoganHsu/pen/vEYXeZe?editors=1011)|
| 12 | Toung |[Codepen](https://codepen.io/Toung/pen/QwWgMpX)|
| 13 | 姜承 |[Codepen](https://codepen.io/Troy0718/pen/xbxavZG?editors=0011)|
| 14 | Sonia |[Codepen](https://codepen.io/YUJOU/pen/qEEmNdV?editors=0011)|
| 15 | jinliu214 |[Codepen](https://codepen.io/jinliu214/pen/YPXXLYx?editors=1111)|
| 16 | shin_kai |[Codepen](https://codepen.io/KAI-SHIN-the-animator/pen/zxrZjaO)|

```css=
|  |  |[Codepen]()|
```
