</> register: UseFormRegister
This method allows you to register an input or select element and apply validation rules in React Hook Form. Validation rules are all based on the HTML standard and also allow for custom validation methods.
Props
| Name | Type | Description |
|---|---|---|
name | string | Input's name. |
options | RegisterOptions | Input's behavior. |
Return
| Name | Type | Description |
|---|---|---|
ref | React.Ref | React element ref used to connect hook form to the input. |
name | string | Input's name being registered. |
onChange | ChangeHandler | onChange prop to subscribe to the input change event. |
onBlur | ChangeHandler | onBlur prop to subscribe to the input blur event. |
min | string | number | Since v7.21.0 Present only when progressive is true; reflects the min rule if one was set (otherwise undefined). |
max | string | number | Since v7.21.0 Present only when progressive is true; reflects the max rule if one was set (otherwise undefined). |
maxLength | number | Since v7.21.0 Present only when progressive is true; reflects the maxLength rule if one was set (otherwise undefined). |
minLength | number | Since v7.21.0 Present only when progressive is true; reflects the minLength rule if one was set (otherwise undefined). |
pattern | string | Since v7.21.0 Present only when progressive is true; reflects the pattern rule if one was set (otherwise undefined). |
required | boolean | Since v7.21.0 Present only when progressive is true; reflects the required rule if one was set (otherwise false). |
disabled | boolean | Since v7.21.0 optional. Present when the disabled option is set. |
This is how submitted values will look like:
| Input Name | Submit Result |
|---|---|
| register("firstName") | { firstName: value } |
| register("name.firstName") | { name: { firstName: value } } |
| register("name.firstName.0") | { name: { firstName: [ value ] } } |
Options
By selecting the register option, the API table below will get updated.
These are validation rules, not native HTML attributes. They run based on the form's mode and don't block typing. To also forward required, min, max, minLength, maxLength, and pattern as native attributes on the input, set progressive to true on useForm.
| Name | Description |
|---|---|
requiredboolean | Indicates that the input must have a value before the form can be submitted. Note: This config aligns with web constrained API for required input validation, for object or array input types, use the validate function instead. |
maxLengthnumber | The maximum length of the value to accept for this input. |
minLengthnumber | The minimum length of the value to accept for this input. |
maxnumber | The maximum value to accept for this input. |
minnumber | The minimum value to accept for this input. |
patternRegExp | The regex pattern for the input. Note: RegExp with the /g flag keeps track of the last index where a match occurred. |
validateFunction | | Validate function will be executed on its own without depending on other validation rules included in the required attribute. The function receives the field value (and, Since v7.42.0 optionally the full form values as a second argument) and must return one of:
Note: for object or array input data, it's recommended to use the validate function for validation as the other rules mostly apply to strings, arrays of strings, numbers, and booleans. |
valueAsNumberboolean | Returns Number normally. If something goes wrong NaN will be returned.
|
valueAsDateboolean | Returns Date normally. If something goes wrong Invalid Date will be returned.
|
setValueAs<T>(value: any) => T | Return input value by running through the function.
|
disabledboolean = false | Since v7.13.0 Set disabled to true will lead input value to be undefined and input control to be disabled.
|
onChange(e: SyntheticEvent) => void | Since v7.16.0 onChange function event to be invoked in the change event. |
onBlur(e: SyntheticEvent) => void | Since v7.16.0 onBlur function event to be invoked in the blur event. |
valueunknown | Since v7.8.0 Set up value for the registered input. This prop should be utilised inside useEffect or invoked once, each re-run will update or overwrite the input value which you have supplied. |
shouldUnregisterboolean | 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. |
depsstring | string[] | Since v7.14.0 When this field's own validation runs (e.g. via its registered onChange/onBlur), the fields listed in deps will also be re-validated. Calling trigger() manually does not honor deps. |
Name is required and must be unique (except for native radio and checkbox inputs).
Names must not start with a number or use numbers as standalone keys, and should avoid special characters. For TypeScript consistency, only dot syntax is supported—bracket syntax (
[]) will not work for array form values.register("test.0.firstName") // ✅register("test[0].firstName") // ❌- Disabled inputs return
undefinedas their form value. If you need to prevent user edits while preserving the value, usereadOnlyor disable the entirefieldset. Here is an example. - Changing an input’s
nameon each render causes it to be re-registered as a new field. To ensure consistent behavior, keep input names stable across renders. - Input values and references are not automatically removed on unmount.
Use
unregisterto explicitly remove them when needed. Calling
registeragain on the same name merges the new options into the existing ones — it does not replace them — so individual register options cannot be removed usingundefinedor{}. You can update individual attributes instead.register('test', { required: true });register('test', {}); // ❌register('test', undefined); // ❌register('test', { required: false }); // ✅- There are certain keywords that should be avoided to prevent conflicts with type checks. They are
refand_f.
Examples
Register input or select
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>)}
Custom async validation
import { useForm } from "react-hook-form"import { checkProduct } from "./service"export default function App() {const { register, handleSubmit } = useForm()return (<form onSubmit={handleSubmit(console.log)}><select{...register("category", {required: true,})}><option value="">Select...</option><option value="A">Category A</option><option value="B">Category B</option></select><inputtype="text"{...register("product", {validate: {checkAvailability: async (product, { category }) => {if (!category) return "Choose a category"if (!product) return "Specify your product"const isInStock = await checkProduct(category, product)return isInStock || "There is no such product"},},})}/><input type="submit" /></form>)}
Video
Tips
Destructuring assignment
const { onChange, onBlur, name, ref } = register('firstName');// Include a type check against the field path with the name you have supplied.<inputonChange={onChange} // assign onChange eventonBlur={onBlur} // assign onBlur eventname={name} // assign name propref={ref} // assign ref prop/>// same as above<input {...register('firstName')} />
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 of 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, minLength: 8 });<TextInput onTextChange={(value) => setValue("firstName", value)} />
How to work with innerRef, inputRef?
When the custom input component doesn't expose the ref correctly, you can get it working via the following method.
// not working, because ref is not assigned<TextInput {...register('test')} />const firstName = register('firstName', { required: true })<TextInputname={firstName.name}onChange={firstName.onChange}onBlur={firstName.onBlur}inputRef={firstName.ref} // you can achieve the same for different ref names such as innerRef/>
Thank you for your support
If you find React Hook Form to be useful in your project, please consider starring and supporting it.