# register

> Register an input with React Hook Form to enable validation, value tracking, and form submission. Supports text, checkbox, select, and more.

Source: https://react-hook-form.com/docs/useform/register

## `register:` [UseFormRegister](https://react-hook-form.com/ts#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`](https://react-hook-form.com/docs/useform#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.                                                                                  |

> **note**
>
> 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.

> **note**
>
> These are validation rules, not native HTML attributes. They run based on the form's [`mode`](https://react-hook-form.com/docs/useform#mode) and don't block typing. To also forward `required`, `min`, `max`, `minLength`, `maxLength`, and `pattern` as native attributes on the input, set [`progressive`](https://react-hook-form.com/docs/useform#progressive) to `true` on `useForm`.
>

<div style={{ background: 'var(--color-options)', padding: 20 }}>

| Name                                                                          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `required` `boolean`                                    | Indicates that the input must have a value before the form can be submitted.<br/><br/>**Note:** This config aligns with web constrained API for required input validation, for object or array input types, use the validate function instead.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `maxLength` `number`                                    | The maximum length of the value to accept for this input.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `minLength` `number`                                    | The minimum length of the value to accept for this input.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `max` `number`                                          | The maximum value to accept for this input.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `min` `number`                                          | The minimum value to accept for this input.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `pattern` `RegExp`                                      | The regex pattern for the input.<br/><br/>**Note:** `RegExp` with the `/g` flag keeps track of the last index where a match occurred.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `validate` Function \|<br/>`Record<string, Function>` | 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:<br/><ul><li>`true` or `undefined` — field is valid (both are treated identically; explicit `return true` is conventional but not required)</li><li>A `string` — field is invalid; the string is used as the error message</li><li>`false` — field is invalid with no custom message (a generic error is used)</li></ul>Pass an object of named functions to run multiple independent validations, each with its own error message.<br/><br/>**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. |
| `valueAsNumber` `boolean`                               | Returns `Number` normally. If something goes wrong `NaN` will be returned.<br/><ul><li>`valueAs` process is happening **before** validation.</li><li>Only applies to number input, but without any data manipulation.</li><li>Does not transform `defaultValue` or `defaultValues`.</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `valueAsDate` `boolean`                                 | Returns `Date` normally. If something goes wrong `Invalid Date` will be returned.<br/><ul><li>`valueAs` process is happening **before** validation.</li><li>Only applies to input.</li><li>Does not transform `defaultValue` or `defaultValues`.</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `setValueAs` \<T\>(value: any) => T                   | Return input value by running through the function.<br/><ul><li>`valueAs` process is happening **before** validation. Also, `setValueAs` is ignored if either `valueAsNumber` or `valueAsDate` are true.</li><li>Only applies to text input.</li><li>Does not transform `defaultValue` or `defaultValues`.</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `disabled` `boolean = false`                            | _(since v7.13.0)_ Set `disabled` to `true` will lead input value to be `undefined` and input control to be disabled.<br/><ul><li>`disabled` prop will also omit built-in validation rules.</li><li>For schema validation, you can leverage the `undefined` value returned from input or context object.</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `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.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `value` `unknown`                                       | _(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.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `shouldUnregister` `boolean`                            | Input will be unregistered after unmount and `defaultValues` will be removed as well.<br/><br/>**Note:** this prop should be avoided when using with `useFieldArray` as unregister function gets called after input unmount/remount and reorder.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `deps` `string \| 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`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |

</div>

<div style={{ background: 'var(--color-options)', padding: 20 }}>

| Name                                                                                                           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `required` string \|<br/>{ value: boolean, message: string } | Indicates that the input must have a value before the form can be submitted. <br/><br/>**Note:** This config aligns with web constrained API for required input validation, for object or array input types, use the validate function instead.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `maxLength` `{ value: number, message: string }`               | The maximum length of the value to accept for this input.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `minLength` `{ value: number, message: string }`               | The minimum length of the value to accept for this input.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `max` `{ value: number, message: string }`                     | The maximum value to accept for this input.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `min` `{ value: number, message: string }`                     | The minimum value to accept for this input.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `pattern` `{ value: RegExp, message: string }`                 | The regex pattern for the input.<br/><br/>**Note:** `RegExp` with the `/g` flag keeps track of the last index where a match occurred.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `validate` Function \|<br/>`Record<string, Function>`                                  | 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:<br/><ul><li>`true` or `undefined` — field is valid (both are treated identically; explicit `return true` is conventional but not required)</li><li>A `string` — field is invalid; the string is used as the error message</li><li>`false` — field is invalid with no custom message (a generic error is used)</li></ul>Pass an object of named functions to run multiple independent validations, each with its own error message.<br/><br/>**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. |
| `valueAsNumber` `boolean`                                                                | Returns `Number` normally. If something goes wrong `NaN` will be returned.<br/><ul><li>`valueAs` process is happening **before** validation.</li><li>Only applies to number input, but without any data manipulation.</li><li>Does not transform `defaultValue` or `defaultValues`.</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `valueAsDate` `boolean`                                                                  | Returns `Date` normally. If something goes wrong `Invalid Date` will be returned.<br/><ul><li>`valueAs` process is happening **before** validation.</li><li>Only applies to input.</li><li>Does not transform `defaultValue` or `defaultValues`.</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `setValueAs` \<T\>(value: any) => T                                                    | Return input value by running through the function.<br/><ul><li>`valueAs` process is happening **before** validation. Also, `setValueAs` is ignored if either `valueAsNumber` or `valueAsDate` are true.</li><li>Only applies to text input.</li><li>Does not transform `defaultValue` or `defaultValues`.</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `disabled` `boolean = false`                                                             | _(since v7.13.0)_ Set `disabled` to `true` will lead input value to be `undefined` and input control to be disabled.<br/><ul><li>`disabled` prop will also omit built-in validation rules.</li><li>For schema validation, you can leverage the `undefined` value returned from input or context object.</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `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.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `value` `unknown`                                                                        | _(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.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `shouldUnregister` `boolean`                                                             | Input will be unregistered after unmount and `defaultValues` will be removed as well.<br/><br/>**Note:** this prop should be avoided when using with `useFieldArray` as unregister function gets called after input unmount/remount and reorder.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `deps` `string \| 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`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |

</div>

 
> **Important: Rules**
>
> <ul>
>   <li>
>     <strong>Name</strong> is <strong>required</strong> and must be <strong>unique</strong>
>         (except for native radio and checkbox inputs).
>   </li>
>   <li>
>     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 (<code>[]</code>) will not work for array form values.
>
> ```javascript
> register("test.0.firstName") // ✅
> register("test[0].firstName") // ❌
> ```
>
>   </li>
>   
>   <li> Disabled inputs return <code>undefined</code> as their form value.
>         If you need to prevent user edits while preserving the value, use
>         <code>readOnly</code> or disable the entire <code>fieldset</code>. Here is an [example](https://codesandbox.io/s/react-hook-form-disabled-inputs-oihxx).</li>
>   
>   <li>Changing an input’s <code>name</code> on each render causes it to be re-registered as a new field.
>         To ensure consistent behavior, keep input names stable across renders.</li>
>   
>   <li>Input values and references are not automatically removed on unmount.
>         Use <a href="/docs/useform/unregister"><code>unregister</code></a> to explicitly remove them when needed.</li>
>   
>   <li>
>   Calling <code>register</code> again on the same name merges the new options into the existing ones — it does not replace them — so individual register options cannot be removed using `undefined` or `{}`. You can update individual attributes instead.
>   
> ```javascript
> register('test', { required: true });
> register('test', {}); // ❌
> register('test', undefined); // ❌
> register('test', { required: false });  // ✅
> ```
>   
>   </li>
>
>     <li>There are certain keywords that should be avoided to prevent conflicts with type checks. They are `ref` and `_f`.</li>
>
> </ul>
>

### Examples

---

**Register input or select**

[Open in CodeSandbox](https://codesandbox.io/s/register-is0sfo)

```javascript
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**

```javascript
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>

      <input
        type="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>
  )
}
```

**File input**

A file input's value is a `FileList`, not a string. `required` works as usual, use `validate` to check things like file size, and build a `FormData` from the files when you submit.

```tsx
import { useForm } from "react-hook-form"

type FormValues = { avatar: FileList }

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<FormValues>()

  const onSubmit = async ({ avatar }: FormValues) => {
    const body = new FormData()
    body.append("avatar", avatar[0])
    await fetch("/api/avatar", { method: "POST", body })
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        type="file"
        accept="image/*"
        {...register("avatar", {
          required: "Choose a file",
          validate: (files) =>
            !files?.[0] || files[0].size < 2_000_000 || "Max size is 2 MB",
        })}
      />
      {errors.avatar && <p>{errors.avatar.message}</p>}
      <input type="submit" />
    </form>
  )
}
```

### Video

---

[Watch on YouTube](https://www.youtube.com/watch?v=JFIpCoajYkA)

### Tips

---

#### Destructuring assignment

```javascript
const { onChange, onBlur, name, ref } = register('firstName');
// Include a type check against the 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')} />
```

#### Custom Register

You can also register inputs with `useEffect` and treat them as virtual inputs. For controlled components, we provide a custom hook [useController](https://react-hook-form.com/docs/usecontroller) and [Controller](https://react-hook-form.com/docs/usecontroller/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](https://react-hook-form.com/docs/useform/setvalue).

```javascript
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.

```javascript
// 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 names such as innerRef
/>
```

If you also need the input's ref yourself, see [How to share ref usage](https://react-hook-form.com/faqs#Howtosharerefusage).

### Troubleshooting

---

#### A number input is submitted as a string

**Why it happens:**

Input values in the DOM are always strings, so `<input type="number">` gives you `"5"`, not `5`.

**Fix:**

Add `valueAsNumber`, or `setValueAs` for your own conversion:

```javascript
<input type="number" {...register("age", { valueAsNumber: true })} />
```

#### A field in a custom input component is missing from the submitted data

**Why it happens:**

`register` reads the value through the `ref` of the actual `<input>`. If your component takes the props but does not pass `ref` on to the `<input>`, the field has no value and cannot be focused on errors.

**Fix:**

Pass all props, including `ref`, to the `<input>`. If the component uses a different prop name such as `inputRef`, see [How to work with `innerRef`, `inputRef`](#HowtoworkwithinnerRefinputRef).

#### A field registered with `disabled: true` is missing from the submitted data

**Why it happens:**

Disabling a field through `register` excludes its value from the data passed to `handleSubmit`.

**Fix:**

If the user should see the value but not change it, and you still need it in the submitted data, use `readOnly` instead: `<input readOnly {...register("id")} />`.
