useController:
(props?: UseControllerProps) => { field: object, fieldState: object, formState: object }
This custom hook is what powers Controller
, and shares the same props and methods as Controller
. It's useful to create reusable Controlled input, while Controller
is the flexible option to drop into your page or form.
Props
The following table contains information about all the arguments for useController
.
Name | Type | Required | Description |
---|---|---|---|
name | string | ✓ | Unique name of your input. |
control | Object | control object is from invoking useForm . Optional when using FormProvider . | |
defaultValue | any | The same as an uncontrolled component's defaultValue . When passing a boolean value, it will be treated as checkbox input. For more details, see useForm's defaultValues section.
| |
rules | Object | Validation rules in the same format as for register .
|
Return
The following table contains information about properties which useController
produce.
Object Name | Name | Type | Description |
---|---|---|---|
field | onChange | (value: any) => void | A function which send value to hook form and should be assigned with |
onBlur | (value: any) => void | A function which send value to hook form and should be assigned with | |
value | unknown | The value of this controlled component. | |
ref | |||
Assign | |||
fieldState | invalid | boolean | Invalid state for current input. |
isTouched | boolean | Touched state for current controlled input. | |
isDirty | boolean | Dirty state for current controlled input. | |
error | object | error for this specific input. | |
formState | isSubmitSuccessful | boolean | Indicate the form was successfully submitted. |
isDirty | boolean | Set to | |
isSubmitted | boolean | Set to | |
dirtyFields | object | An object with the user-modified fields. Make sure to provide all inputs' defaultValues at the useForm, so hook form can compare with the | |
touchedFields | object | An object containing all the inputs the user has interacted with. | |
isSubmitting | boolean |
| |
submitCount | number | Number of times the form was submitted. | |
isValid | boolean | Set to | |
isValidating | boolean | Set to |
import React from "react"; import { TextField } from "@material-ui/core"; import { useController, useForm } from "react-hook-form"; function Input({ control, name }) { const { field: { ref, ...inputProps }, fieldState: { invalid, isTouched, isDirty }, formState: { touchedFields, dirtyFields } } = useController({ name, control, rules: { required: true }, defaultValue: "", }); return <TextField {...inputProps} inputRef={ref} />; } function App() { const { control } = useForm(); return <Input name="firstName" control={control} />; }
import * as React from "react"; import { useForm, useController } from "./src"; function Input(props) { const { field, fieldState } = useController(props); return ( <div> <input {...field} placeholder={props.name} /> <p>{fieldState.isTouched && "Touched"}</p> <p>{fieldState.isDirty && "Dirty"}</p> <p>{fieldState.invalid ? "invalid" : "valid"}</p> </div> ); } export default function App() { const { handleSubmit, control } = useForm({ defaultValues: { FirstName: "" }, mode: "onChange" }); const onSubmit = (data) => console.log(data); return ( <form onSubmit={handleSubmit(onSubmit)}> <Input control={control} name="FirstName" rules={{ required: true }} /> <input type="submit" /> </form> ); }
Tips
Do not
register
input again. This custom hook is made to take care the registration process.const { field } = useController({ name: 'test' }) <input {...field} /> // ✅ <input {...field} {...register('test')} /> // ❌ double up the registration
It's ideal to use single
useController
per component. If you need to use more than one, make sure you rename the prop or even consider to useController
instead.const { field: input } = useController({ name: 'test' }) const { field: checkbox } = useController({ name: 'test1' }) <input {...input} /> <input {...checkbox} />