--- 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 連結貼至底下回報就算完成了喔! 解答位置請參考下圖(需打開程式碼的部分觀看) ![](https://i.imgur.com/vftL5i0.png) <!-- 解答: ``` 寫法一: <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)|