register: (name: string, RegisterOptions?) => ({ onChange, onBlur, name, ref })
This method allows you to register an input or select element and apply validation rules to React Hook Form. Validation rules are all based on the HTML standard and also allow for custom validation methods.
By invoking the register function and supplying an input's name, you will receive the following methods:
Props
Name | Type | Description |
---|---|---|
onChange | ChangeHandler |
|
onBlur | ChangeHandler |
|
ref | React.Ref<any> | Input reference for hook form to register. |
name | string | Input's name being registered. |
Input Name | Submit Result |
---|---|
register("firstName") | {firstName: 'value'} |
register("name.firstName") | {name: { firstName: 'value' }} |
register("name.firstName.0") | {name: { firstName: [ 'value' ] }} |
Return
Tip:: What's happened to the input after invoke register API:
const { onChange, onBlur, name, ref } = register('firstName'); // include type check against field path with the name you have supplied. <input onChange={onChange} // assign onChange event onBlur={onBlur} // assign onBlur event name={name} // assign name prop ref={ref} // assign ref prop /> // same as above <input {...register('firstName')} />
Options
By selecting the register option, the API table below will get updated.
Name | Description | Code Examples |
---|---|---|
ref React.Ref | React element ref |
|
required boolean | A Boolean which, if true, indicates that the input must have a value before the form can be submitted. You can assign a string to return an error message in the Note: This config aligns with web constrained API for required input validation, for |
|
maxLength
| The maximum length of the value to accept for this input. |
|
minLength
| The minimum length of the value to accept for this input. |
|
max
| The maximum value to accept for this input. |
|
min
| The minimum value to accept for this input. |
|
pattern
| The regex pattern for the input. Note: A RegExp object with the /g flag keeps track of the lastIndex where a match occurred. |
|
validate Function | Object | You can pass a callback function as the argument to validate, or you can pass an object of callback functions to validate all of them. This function will be executed on its own without depending on other validation rules included in the Note: for |
|
valueAsNumber:boolean | Returns a Number normally. If something goes wrong
|
|
valueAsDate:boolean | Returns a
|
|
setValueAs:<T>(value: any) => T | Return input value by running through the function.
|
|
disabled boolean = false | Set
For schema validation, you can leverage the |
|
onChange (e: SyntheticEvent) => void |
|
|
onBlur (e: SyntheticEvent) => void |
|
|
value unknown | Set up value for the registered input. This prop should be utilised inside |
|
shouldUnregister:boolean | Input will be unregistered after unmount and defaultValues will be removed as well. Note: this prop should be avoided when using with |
|
deps:string | string[] | Validation will be triggered for the dependent inputs,it only limited to |
|
Rules
name
is required and unique (except native radio and checkbox). Input name supports both dot and bracket syntax, which allows you to easily create nested form fields.name
can neither start with a number nor use number as key name.we are using dot syntax only for typescript usage consistency, so bracket
[]
will not work for array form value.register('test.0.firstName'); // ✅ register('test[0]firstName'); // ❌
disabled
input will result in anundefined
form value. If you want to prevent users from updating the input, you can usereadOnly
or disable the entire <fieldset />. Here is an example.To produce an array of fields, input names should be followed by a dot and number. For example:
test.0.data
Changing the name on each render will result in new inputs being registered. It's recommend to keep static names for each registered input.
Input value and reference will no longer gets removed based on unmount. You can invoke unregister to remove that value and reference.
Individual register option can't be removed by
undefined
or{}
. You can update individual attribute instead.register('test', { required: true }); register('test', {}); // ❌ register('test', undefined); // ❌ register('test', { required: false }); // ✅
Examples
import * as React from "react"; import { useForm } from "react-hook-form"; export default function App() { const { register, handleSubmit } = useForm({ defaultValues: { firstName: '', lastName: '', category: '', checkbox: [], radio: '' } }); return ( <form onSubmit={handleSubmit(console.log)}> <input {...register("firstName", { required: true })} placeholder="First name" /> <input {...register("lastName", { minLength: 2 })} placeholder="Last name" /> <select {...register("category")}> <option value="">Select...</option> <option value="A">Category A</option> <option value="B">Category B</option> </select> <input {...register("checkbox")} type="checkbox" value="A" /> <input {...register("checkbox")} type="checkbox" value="B" /> <input {...register("checkbox")} type="checkbox" value="C" /> <input {...register("radio")} type="radio" value="A" /> <input {...register("radio")} type="radio" value="B" /> <input {...register("radio")} type="radio" value="C" /> <input type="submit" /> </form> ); }
import * as React from "react"; import { useForm } from "react-hook-form"; export default function App() { const { register, handleSubmit } = useForm(); const onSubmit = (data) => alert(JSON.stringify(data)); return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register("firstName")} placeholder="First name" /> <input {...register("lastName")} placeholder="Last name" /> <select {...register("category")}> <option value="">Select...</option> <option value="A">Category A</option> <option value="B">Category B</option> </select> <input type="submit" /> </form> ); }
Video
The following video explain register
API in detail.
Tips
Custom Register
You can also register
inputs with useEffect
and treat them as virtual inputs. For controlled components, we provide a custom hook useController and Controller component to take care this process for you.
If you choose to manually register fields, you will need to update the input value with setValue.
register('firstName', { required: true, min: 8 }); <TextInput onTextChange={(value) => setValue('lastChange', value))} />
How to work with innerRef, inputRef?
When the custom input component didn't expose ref correctly, you can get it working via the following.
// not working, because ref is not assigned <TextInput {...register('test')} /> const firstName = register('firstName', { required: true }) <TextInput name={firstName.name} onChange={firstName.onChange} onBlur={firstName.onBlur} inputRef={firstName.ref} // you can achieve the same for different ref name such as innerRef /> // correct way to forward input's ref const Select = React.forwardRef(({ onChange, onBlur, name, label }, ref) => ( <select name={name} ref={ref} onChange={onChange} onBlur={onBlur}> <option value="20">20</option> <option value="30">30</option> </select> ));
Thank you for your support
If you find React Hook Form to be useful in your project, please consider to star and support it.