目錄
control
control是useForm的回傳值,是個包了註冊component的方法的物件
但不該
試著存取control內的任何屬性
,如果真的要說的話,它其實只能和Controller一起用
Controller
用Controller包裹
組件可以讓input變成controlled component
舉例來說,像這篇提到由於MUI抽象得很深,input或者select被藏起來了,所以無法直接用register來註冊欄位
,這時就會需要useController或Controller,客製化的組件也可能會用到Controller
至於為什麼input藏得很深就無法直接註冊
,是因為無法直接傳遞ref給input
,而react-hook-form傾向於用uncontrolled component,然後透過ref來控制DOM
在使用Controller時會需要提供以下的props
name
功能和key差不多,是一個不能重複
的字串render
一個回傳你要註冊的controlled component
的function
react-hook-form會幫你把controlled component整合進去,因此就能使用field、fieldState、formState了defaultValue
如果會用到reset的話,那要提供dedefaultValue,且注意絕對不要提供undefined
const { handleSubmit, control } = useForm({
ReactSelect: { value: "vanilla", label: "Vanilla" },
});
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<Controller
name="ReactSelect"
control={control}
render={({ field }) => (
<ReactSelect
isClearable
{...field}
options={[
{ value: "apple", label: "Apple" },
{ value: "strawberry", label: "Strawberry" },
{ value: "banana", label: "Banana" }
]}
/>
)}
/>
</form>
);
useController
和Controller+control一樣用於有controlled component的場景
它接收
name、control、defaultValues、rule...等,其中control
是來自useForm回傳,通常
只在用到FormProvider
的場景使用,rule則是用於驗證
並回傳以下幾個東西field、formState、fieldState,field類似於useForm回傳的register,
field.ref
則用於連結controlled component和react-hook-form
,當handleSubmit觸發時,會進行驗證,然後focus有error的input
至於formState和fieldState與useForm差不多
const {
field,
fieldState: { invalid, isTouched, isDirty },
formState: { touchedFields, dirtyFields }
} = useController({
name: 'Name',
control,
rules: { required: true },
});
return (
<>
<TextField
onChange={field.onChange}
onBlur={field.onBlur}
value={field.value}
name={field.name} // 欄位名,不可重複
inputRef={field.ref} // ref是用於連結react-hook-form和這個input
/>
{/ * 等同於上段 * /}
<TextField
{...field}
/>
</>
);