react-hook-form 使用小結

表單狀態管理曾經一直是讓前端頭疼的問題,錯誤提示,校驗規則,動態表單,重置。。。搞得人頭大。好在近幾年也出現了不少好的社區方案,比如 Formik, react-hook-form, react-final-form等等,今天我們來談談其中的 react-hook-form。

useForm

useForm 是最基礎的表單狀態管理鉤子,它接受以下參數:

const {
  handleSubmit,
  watch
} = useForm({
  defaultValues: {},
  mode: 'onSubmit' // onChange | onBlur | onSubmit | onTouched | all
})

mode 可以控制觸發校驗的時機,如果我們希望用戶能儘快感知到填寫出錯了,可以使用 'all';

defaultValues, 如果表單從後臺拉下來數據,有初始值,可以從這裏傳進去。

rules

rules可以用來校驗值,支持以下字段:

{
required: true,
maxLength; // 最大長度
minLength; //最小長度
max: 5 // 最大值
min: 5 // 最小值
pattern: /1\d{12}/
validate: (v) => v > 100
validate: {
	greaterThan: (v) => v > 100,
	lessThan: (v) => v< 200
	}
}

使用<Controller />來和UI庫集成

使用useForm返回的register函數,可以很方便地使用原生html元素構建一個表單,但是大部分情況下,我們是使用UI庫來開發表單的。

<Controller/>組件接受control, name,rules和 render函數等作爲屬性,render函數接受field, fieldState, formState3個參數:field裏面包括用來控制字段的onChange函數和value,fieldState 包含字段的校驗信息。通過這些信息,我們就可以控制這個字段是應該怎麼渲染;

    field: { onChange, onBlur, value, name, ref },
    fieldState: { invalid, isTouched, isDirty, error },
    formState,
<Controller
  control={control}
  rules={{ required: true }}
  name="test"
  render={({
    field: { onChange, onBlur, value, name, ref },
    fieldState: { invalid, isTouched, isDirty, error },
    formState,
  }) => (
    <Checkbox
      onBlur={onBlur} // notify when input is touched
      onChange={onChange} // send value to hook form
      checked={value}
      inputRef={ref}
    />
  )}
/>

watch和useWatch 構建動態表單

經常有這樣的場景,就是一個輸入,會影響接下來的表單展示。由於useForm的表單狀態發生變化,並不一定會觸發重新渲染,當我們需要當值發生變化的時候更新UI,我們需要用到useWatch或者watch;

假設有這麼一個場景,我們需要實時回顯用戶的輸入,那麼可以這麼寫:

const watchedName = watch('name', '');

return <div>
    <label>Name</label>
    <input
        type="text"
            {...register("name", { required: true, maxLength: 50 })}
    />
    <div>name: {watchedName}</div>
</div>

這時,當輸入框的字段更新時,就會觸發重新渲染,從而回顯用戶輸入的值。那麼watchuseWatch的區別是啥呢,watch是 useForm鉤子的返回值,useWatch是一個全新的鉤子函數,在一些不需要父組件更新的場景下,可以獲得更好的性能。下面這個例子將watch傳入子組件,可以發現,子組件更新時父組件也更新了。

useFieldArray來新增表單項

我們經常會遇到這樣的場景--新增表單項,比如新增收貨地址。use-hook-form爲我們提供了useFieldArray這個hook來完成這些工作:

  const { register, control, handleSubmit, reset, watch } = useForm({
    defaultValues: {
      test: [{ firstName: "Bill", lastName: "Luo" }]
    }
  });
  const {
    fields,
    append,
    prepend,
    remove,
    swap,
    move,
    insert,
    replace
  } = useFieldArray({
    control,
    name: "test"
  });

我們可以使用prepend在隊首插入一個表單項,append在隊尾插入一個表單項,remove來去掉一個表單項。當然如果我們希望實時顯示錶單項裏的數據的時候,還是要使用watchuseWatch

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章