React Hook Form入門 | 純管理表單並完成與第三方框架配合的選擇 (下篇)

React Hook Form入門 | 純管理表單並完成與第三方框架配合的選擇 (下篇)

·

2 min read

此為ReactHookForm 介紹的下篇,如果還沒看過上篇的人可以先前往了解ReactHookForm基礎API。

mode 驗證時機

有了驗證條件,我們自然需要設定驗證時機!
常見的驗證時機有當使用者改變了input的值(onChange)、當input Focus狀態取消(onBlur)、送出表單時一次驗證(onSubmit),這些我們在useForm時都可以做選擇,甚至所有驗證時機都要一次上的話可以填入all
無論怎麼填寫,都會在SunmitHandle觸發時,再一次做驗證。

  const {
    register,
  } = useForm({
    mode: "onChange" // 直接填入方法
  });

trigger 手動驗證

雖然有mode,但有時我們也有需要手動驗證欄位的情況,這時候我們可以使用trigger
以下範例,雖然我們沒有指定驗證mode,所以只有SunmitHandle時會驗證,但我們新增了一顆Button綁定Click事件,當該Button點擊時會就驗證firstName欄位。

trigger也可以不填入參數,如trigger();,React Hook From會驗證整份表單所有validation

  const {
    register,
    trigger, // 將trigger這個方法解構出來
  } = useForm({});
  <input {...register("userName", { required: true })} />
  {errors.firstName && <p>使用者名稱為必填</p>}

  <button
      type="button"
      onClick={() => {
          trigger('userName');
      }}
  >

setError 手動給予錯誤狀態

這是我很常用在當使用者註冊時,會有一些與input狀態無關的錯誤,例如一些需要發出API才能得知到狀態。因為和inputvalidation無關,所以我們可以手動給予這個錯誤狀態。

以下用一個無論怎麼送出都會出現找不到使用者名稱的表單來做範例:

  const {
    register,
    formState: { errors },
    setError, // 將setError這個方法解構出來
  } = useForm({});
  <input {...register("userName", { required: true })} />

  <button
      type="button"
      onClick={() => {
          setError("root", 
          { type: "userNameNotfound", 
            message: "找不到此使用者" })
      }}
  >
  {errors.root.type === 'userNameNotfound' && <p>{errors.root.types.userNameNotfound}</p>}
// ⬆️ 點擊Button後,畫面渲染<p>找不到此使用者</p>

clearErrors 手動清除錯誤狀態

如果setError 沒有對應的validation,我們就要有時機手動清除這個錯誤,我們把上述的程式碼修改為當使用者重新輸入input時會清除錯誤狀態。

  const {
    register,
    formState: { errors },
    setError,
    clearErrors, // 將clearError這個方法解構出來
  } = useForm({});

  <input {...register("userName", 
         { required: true,
           onChange: ()=>clearErrors("root.userNameNotfound")
          // ⬆️ 當使用者重新輸入值時即清除錯誤狀態。
         })} 

  />

  <button
      type="button"
      onClick={() => {
          setError("root", 
          { type: "userNameNotfound", 
            message: "找不到此使用者" })
      }}
  >
  {errors.root.type === 'userNameNotfound' && <p>{errors.root.types.userNameNotfound}</p>}
// ⬆️ 點擊Button後,畫面渲染<p>找不到此使用者</p>

Control 渲染外部元件

在上篇有提到React Hook Form 對整合UI libraries也非常友善,主要由Contorl 來協助React Hook Fomr註冊的表單傳遞事件。我們用 react-tailwindcss-datepicker 來做演示:

  const {
    register,
    control // 將control這個方法解構出來
  } = useForm({});
<Controller
  name="birthday" // 相當於register的name,必須是唯一值
  control={control}
  // ⬇️在此render 我們的外部元件,並且將需要用的的方法從field解構出來
  render={({ field: { onChange, value } }) => (
    <Datepicker
      useRange={false}
      asSingle={true}
      value={value}
      onChange={onChange}
    />
  )}
/>

我們可以在redner的外部元件中利用field 解構出onChange, onBlur, value, name, ref, error…等等值串入外部元件所需要的props

以下是一個用ReactHookForm結合Tailwinds + Tailwinds DatePicker 的實作:

🌱 結語

React Hook Form 其實還有其他很大的擴展性可以探索,例如結合Yup, Zod , SuperstructJoi 等Schema Validation 來更方便的做確認密碼等等的驗證,如果未來覺得有做筆記的必要會在寫出來與大家分享~

希望這篇文章有幫助到你,有任何錯誤與指教都歡迎留言告訴我!

參考文章:React Hook Form