---
tags: 2022 React 新手讀書會
---
# 🏅 Day 16 |React Hook Form - required
接下來幾天我們要來介紹『React Hook Form』這個套件,此套件提供強大的表單驗證方法,而不論是在此次讀書會的最終任務或是專案開發時,都非常容易遇到表單填寫、送出資料的部分,此時就可以運用此套件來協助做表單確認,一起來練習看看吧!
因為我們是在 CodePen 中練習,所以可以採用 CDN 的方式引入
`
https://cdn.jsdelivr.net/npm/react-hook-form@7.33.1/dist/index.umd.min.js
`
[React Hook Form 文件](https://react-hook-form.com/)
### useForm()
`useForm()` 是 React Hook Form 提供的 Hook,其中會包含我們在表單驗證需要使用的屬性或是函式。例如:
```jsx
const { register, handleSubmit, formState: { errors } } = ReactHookForm.useForm();
```
[useForm() Hook 文件](https://react-hook-form.com/api/useform)
---
#### register
register 是用來註冊 input 元素,當加入 register 之後,就可以讓此 input 的值被加入驗證和送出。而驗證的屬性也同樣是要放到 register 中。舉例像是有一個 input 是輸入帳號,此欄位必填,寫法一如下:
```jsx=
<input name="account" value={users.account} {...register("account", { required: true })} />
```
除此之外,還有另外兩種寫法也都 ok,這邊也一併介紹。
寫法二:
```jsx=
<input {...register("account", { required: "此欄位必填" })} />
```
寫法三 (最推薦用在 input 要有多個驗證)
```jsx=
<input {...register("account", { required: { value: true, message: "此欄位必填" } })} />
```
三者的差異會是在 error 顯示時的呈現方式不同,可以根據你目前表單的複雜程度來做選擇,接下來我們要來了解一下這三者的 errors 的呈現。
[Registerfields 文件](https://react-hook-form.com/get-started#Registerfields)
---
#### formState: { errors }
formState 一樣是從 useForm 帶出的方法,可以讓我們提取 errors 來使用。
對應到上方第一種寫法,他的錯誤呈現可以這樣寫:
```jsx=
{errors.account && <span>此欄位必填</span>}
```
也就是當 errors 有包含 account 屬性時,顯示後面的錯誤訊息。
寫法二對應的錯誤寫法
```jsx=
{errors.account?.message}
```
errors 有包含 account 屬性,且屬性中有包含 message 時,就顯示出設定的 message 錯誤,也就是 `required: "此欄位必填"` 這一段的所設定的文字。寫法三也同上,message 顯示的則是 `{ value: true, message: "此欄位必填" }` 這一段所設定的 message。
[Handleerrors 文件](https://react-hook-form.com/get-started#Handleerrors)
[官方提供視覺化的表單生成器](https://react-hook-form.com/form-builder):透過視覺化的 UI 操作介面就可以建立表單、加入驗證,最後還可以直接複製 Code 來使用。
### 補充
#### 1. 可選串連 `?.`
在 JS 中有提供可選串連運算子`?.` ,可用在深層的物件值存取,如果當要取得的屬性不存在,則會出現 undefined,可以避免找不到兩層以上的屬性而出現錯誤的狀況。舉例:
```js
const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah'
}
};
const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined
const catName = adventurer.cat?.name;
console.log(catName);
// expected output: Dinah
```
[可選串連 MDN 文件](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Optional_chaining)
## 題目
請複製 (右下角 fork)這個[範例](https://codepen.io/hexschool/pen/bGvWgqN),並試著完成題目需求。
- 提供兩個 input 分別是可以輸入帳號和密碼。
- 若沒有填寫就點選『提交』按鈕,則會出現『此欄位必填』的錯誤訊息。
## 回報流程
將答案寫在 CodePen 並複製 CodePen 連結貼至底下回報就算完成了喔!
解答位置請參考下圖(需打開程式碼的部分觀看)

<!-- 解答:
```
寫法一:
<div>
<input name="account" {...register("account", { required: true })} />
{errors.account && <span>此欄位必填</span>}
</div>
<div>
<input name="password" {...register("password", { required: true })} />
{errors.password && <span>此欄位必填</span>}
</div>
寫法二:
<div>
<input name="account" {...register("account", { required: "此欄位必填" })} />
{errors.account?.message}
</div>
<div>
<input {...register("password", { required: "此欄位必填" })} />
{errors.password?.message}
</div>
```
寫法三:
<div>
<input {...register("account", { required: { value: true, message: "此欄位必填" } })} />
{errors.account?.message}
</div>
<div>
<input {...register("password", { required: { value: true, message: "此欄位必填" } })} />
{errors.password?.message}
</div>
-->
回報區
---
| Discord | CodePen / 答案 |
|:-------------:|:-------------------------------------------------------------------:|
| Rice#8043 | [CodePen](https://codepen.io/riecball/pen/RwMBLEQ?editors=1111) |
| yunyun#5215 | [CodePen](https://codepen.io/yun_yunni/pen/mdxoPJG) |
| Vita Ora#4585 | [CodePen](https://codepen.io/showlovezz/pen/dymrMod?editors=0011) |
| HedgehogKU | [CodePen](https://codepen.io/hedgehogkucc/pen/BarbKWg?editors=1010) |
| Mitour#0672 | [CodePen](https://codepen.io/mitour/pen/dymrMWK?editors=0010) |
| wiimax#4564 | [CodePen](https://codepen.io/willismax/pen/QWmoNmy)
| IreneLee#7932 | [CodePen](https://codepen.io/ntjtcxpt-the-animator/pen/xxWBVpY)|
| Eric Su#7798 | [CodePen](https://codepen.io/wc-su/pen/PoRLZMx)|
| Ayre#0016 | [CodePen](https://codepen.io/yichunlin09/pen/xxWBVyj?editors=0010)|
| 布魯諾#7239| [CodePen](https://codepen.io/bruno-yu/pen/wvmOWvG)|
| Dylan_Lin#7320 | [CodePen](https://codepen.io/lin-dylan/pen/NWYJNJN?editors=0110)|
| Kimi#2092 | [CodePen](https://codepen.io/a3216lucy/pen/dymrMdq)|
| yuyu#6310 | [CodePen](https://codepen.io/yuyu0905/pen/bGvZwpM)|
| JarDar#6980 |[codepen](https://codepen.io/jardarpen/pen/ZExPOmm)|
| CofCat#9226 |[codepen](https://codepen.io/cofcat456/pen/OJvqRpv)|
|Evonne#7078|[CodePen](https://codepen.io/Hsu1Fang/pen/QWmoEzm?editors=0011)|
|hiYifang #0736|[CodePen](https://codepen.io/hiYifang/pen/zYWbBMX)|
|彼得#1923|[CodePen](https://codepen.io/shiou-ho/pen/YzagGLr)|
|ChloeLo#4858|[CodePen](https://codepen.io/chloelo/pen/OJvqXbX)|
|LinaChen#1796|[CodePen](https://codepen.io/LinaChen/pen/NWYJbKV)|
| 威爾#1694 | [CodePen](https://codepen.io/WILL_Wu/pen/abYMBzW) |
|JC#8658|[Codepen](https://codepen.io/jcsamoyed/pen/Barbpyj)|
|aka 神魔寶貝|[codepan](https://codepen.io/wei-nie/pen/WNzmoWx?editors=0011)|
| hw#0715 |[Codepen](https://codepen.io/Lhwei/pen/MWVxbrJ?editors=0010)|
| 𝓛𝓊𝒸𝓎#8635 |[Codepen](https://codepen.io/lucygirl/pen/ZExPBPJ)|
|VadaChen#2055|[CodePen](https://codepen.io/vadachen/pen/wvmOogL?editors=0011)|
|Mr.Sean#3825|[CodePen](https://codepen.io/sean_1215/pen/RwMdpPp?editors=1010)|
|SHIN#6075|[CodePen](https://codepen.io/shin9626/pen/OJvqpQE)|
|Neal#0665|[CodePen](https://codepen.io/neallkf/pen/LYdaydr?editors=0010)|
|Otis#8455|[CodePen](https://codepen.io/humming74/pen/KKoEqjB?editors=1011)|
|Wu#0167|[CodePen](https://codepen.io/Xander0705/pen/MWVxEaa)|
|Stanley#2505|[CodePen](https://codepen.io/bigbearada/pen/MWVxOyO)|
|Yiling#4054|[CodePen](https://codepen.io/lin010/pen/OJvqOLV?editors=1010)|
|shin#5792|[CodePen](https://codepen.io/hah1030/pen/ExEMbRr)|
|Ryder#7398|[CodePen](https://codepen.io/rider159159/pen/OJvqmXq)|
|無名#6427|[CodePen](https://codepen.io/Nomoney/pen/bGvZYMR?editors=0010)|
|rainbow#3329|[CodePen](https://codepen.io/g901612002/pen/WNzmxGj)|
|IceSam#7836|[CodePen](https://codepen.io/sam-hsu/pen/BarbGZz)|
|wenyun#2362|[CodePen](https://codepen.io/wenyuncc/pen/vYRPQvL)|
|Chelly#6129|[CodePen](https://codepen.io/chellyhsu/pen/MWVxrod)|
|Timothy#5863|[CodePen](https://codepen.io/timothy_hippo/pen/XWEGoom?editors=0011)|
|Yanyan#3555|[CodePen](https://codepen.io/wei-yi-lee/pen/dymrrMr)|
|thereason#9630|[Codepan](https://codepen.io/esw4soft/pen/mdxgNEE?editors=1011)|
|Robert Lo#9653|[CodePen](https://codepen.io/Robert-Lo/pen/OJvqYmq)|
|easton#3863|[Codepen](https://codepen.io/EastonIsCodingNow/pen/RwMOPwQ)|
| 城堡#2126 | [CodePen](https://codepen.io/tthcastle/pen/RwMOPqE) |
| Kenge#3690 | [CodePen](https://codepen.io/pgkusn/pen/rNdbVqm) |
| 薯餅#3581 | [CodePen](https://codepen.io/ColdingPoTaTo/pen/bGvJdmG) |
| 翔#0859 | [CodePen](https://codepen.io/energy95272z/pen/QWmPjdd) |
| Rocker#6235 | [CodePen](https://codepen.io/RockerLi/pen/MWVRwqb) |
|ねこ*#9385|[Codepan](https://codepen.io/kunpao0104/pen/MWVRwry)|
|Anson#3594|[Codepan](https://codepen.io/huanmingchang/pen/XWEQMWO)|
|栗栗#5900|[CodePen](https://codepen.io/daylilystudio/pen/dymLdZd)|
|charlottelee849#0366|[CodePen](https://codepen.io/charlotte-lee/pen/qBoGBJg?editors=0010)|
|hobby#6565|[CodePen](https://codepen.io/hobbyling/pen/xxWNgZp)|
|yoshidc#0455|[CodePen](https://codepen.io/yoshiyyc/pen/NWYVpzy)|
|eching#9183|[CodePen](https://codepen.io/echin/pen/KKoLedJ?editors=0010)|
| NinaKuo#3332 |[Codepen](https://codepen.io/ninakuo0814/pen/JjLQYBZ)|
| ZengZeng |[Codepen](https://codepen.io/tyzyoko/pen/KKojbYR)|
| Li-Ninja#0471 |[Codepen](https://codepen.io/li-ninja/pen/gOeNNzE?editors=1010)|
| Jasonlu |[Codepen](https://codepen.io/wnptocip/pen/WNJebrQ?editors=0011)|
| TedWang |[Codepen](https://codepen.io/wangtaiyan/pen/dyebYBK?editors=0010)|
|kancheng#3915|[Codepen](https://codepen.io/kancheng/pen/QWrLapy?editors=1111)|
|JimmyChang#5558|[Codepen](https://codepen.io/JimmyChangWenChi/pen/jOxNKEL?editors=1010)|
|huch09#1426|[Codepen](https://codepen.io/subarashii-huch09/pen/xxjxVXe?editors=0010)|
|Ada|[Codepen](https://codepen.io/zggsoagv-the-scripter/pen/RwMmrbP)|
|GL#2256|[Codepen](https://codepen.io/4genie/pen/yLqEJZK)|
|Eshiunm|[Codepen](https://codepen.io/Code-My/pen/rNbqEZR)|