</> Controller
: Component
React Hook Form embraces uncontrolled components and native inputs, however it's hard to avoid working with external controlled component such as React-Select, AntD and MUI. This wrapper component will make it easier for you to work with them.
Props
The following table contains information about the arguments for Controller
.
Name | Type | Required | Description |
---|---|---|---|
name | FieldPath | ✓ | Unique name of your input. |
control | Control | control object is from invoking useForm . Optional when using FormProvider . | |
render | Function | This is a render prop. A function that returns a React element and provides the ability to attach events and value into the component. This simplifies integrating with external controlled components with non-standard prop names. Provides onChange , onBlur , name , ref and value to the child component, and also a fieldState object which contains specific input state. | |
defaultValue | unknown | Important: Can not apply undefined to defaultValue or defaultValues at useForm .
| |
rules | Object | Validation rules in the same format for register options, which includes:required, min, max, minLength, maxLength, pattern, validate | |
shouldUnregister | boolean = false` | Input will be unregistered after unmount and defaultValues will be removed as well. Note: this prop should be avoided when using with useFieldArray as unregister function gets called after input unmount/remount and reorder. | |
disabled | boolean = false` | disabled prop will be returned from field prop. Controlled input will be disabled and its value will be omitted from the submission data. |
Return
The following table contains information about properties which Controller
produces.
Object Name | Name | Type | Description |
---|---|---|---|
field | onChange | (value: any) => void | A function which sends the input's value to the library. It should be assigned to the onChange prop of the input and value should not be undefined . This prop update formState and you should avoid manually invoke setValue or other API related to field update. |
field | onBlur | () => void | A function which sends the input's onBlur event to the library. It should be assigned to the input's onBlur prop. |
field | value | unknown | The current value of the controlled component. |
field | disabled | boolean | The disabled state of the input. |
field | name | string | Input's name being registered. |
field | ref | React.ref | A ref used to connect hook form to the input. Assign ref to component's input ref to allow hook form to focus the error input. |
fieldState | invalid | boolean | Invalid state for current input. |
fieldState | isTouched | boolean | Touched state for current controlled input. |
fieldState | isDirty | boolean | Dirty state for current controlled input. |
fieldState | error | object | error for this specific input. |
formState | isDirty | boolean | Set to true after the user modifies any of the inputs.
|
formState | dirtyFields | object | An object with the user-modified fields. Make sure to provide all inputs' defaultValues via useForm, so the library can compare against the defaultValues
|
formState | touchedFields | object | An object containing all the inputs the user has interacted with. |
formState | defaultValues | object | The value which has been set at useForm's defaultValues or updated defaultValues via reset API. |
formState | isSubmitted | boolean | Set to true after the form is submitted. Will remain true until the reset method is invoked. |
formState | isSubmitSuccessful | boolean | Indicate the form was successfully submitted without any runtime error. |
formState | isSubmitting | boolean | true if the form is currently being submitted. false otherwise. |
formState | isLoading | boolean | true if the form is currently loading async default values.Important: this prop is only applicable to async defaultValues |
formState | submitCount | number | Number of times the form was submitted. |
formState | isValid | boolean | Set to true if the form doesn't have any errors.setError has no effect on isValid formState, isValid will always derived via the entire form validation result. |
formState | isValidating | boolean | Set to true during validation. |
formState | errors | object | An object with field errors. There is also an ErrorMessage component to retrieve error message easily. |
Examples:
Web
import ReactDatePicker from "react-datepicker"import { TextField } from "@material-ui/core"import { useForm, Controller } from "react-hook-form"type FormValues = {ReactDatepicker: string}function App() {const { handleSubmit, control } = useForm<FormValues>()return (<form onSubmit={handleSubmit((data) => console.log(data))}><Controllercontrol={control}name="ReactDatepicker"render={({ field: { onChange, onBlur, value, ref } }) => (<ReactDatePickeronChange={onChange} // send value to hook formonBlur={onBlur} // notify when input is touched/blurselected={value}/>)}/><input type="submit" /></form>)}
React Native
import { Text, View, TextInput, Button, Alert } from "react-native"import { useForm, Controller } from "react-hook-form"export default function App() {const {control,handleSubmit,formState: { errors },} = useForm({defaultValues: {firstName: "",lastName: "",},})const onSubmit = (data) => console.log(data)return (<View><Controllercontrol={control}rules={{required: true,}}render={({ field: { onChange, onBlur, value } }) => (<TextInputplaceholder="First name"onBlur={onBlur}onChangeText={onChange}value={value}/>)}name="firstName"/>{errors.firstName && <Text>This is required.</Text>}<Controllercontrol={control}rules={{maxLength: 100,}}render={({ field: { onChange, onBlur, value } }) => (<TextInputplaceholder="Last name"onBlur={onBlur}onChangeText={onChange}value={value}/>)}name="lastName"/><Button title="Submit" onPress={handleSubmit(onSubmit)} /></View>)}
Video
The following video showcases what's inside Controller and how its been built.
-
It's important to be aware of each prop's responsibility when working with external controlled components, such as MUI, AntD, Chakra UI. Controller acts as a "spy" on your input by reporting and setting value.
- onChange: send data back to hook form
- onBlur: report input has been interacted (focus and blur)
- value: set up input initial and updated value
- ref: allow input to be focused with error
- name: give input an unique name The following codesandbox demonstrate the usages:
- MUI and other components
- Chakra UI components
-
Do not
register
input again. This component is made to take care of the registration process.<Controllername="test"render={({ field }) => {// return <input {...field} {...register('test')} />; ❌ double up the registrationreturn <input {...field} /> // ✅}}/> -
Customise what value gets sent to hook form by transforming the value during
onChange
.<Controllername="test"render={({ field }) => {// sending integer instead of string.return (<input{...field}onChange={(e) => field.onChange(parseInt(e.target.value))}/>)}}/>
Thank you for your support
If you find React Hook Form to be useful in your project, please consider to star and support it.