Skip to content

register

Register uncontrolled/controlled inputs

register: (Ref, 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:

NameTypeDescription
onChangeChangeHandler

onChange prop to subscribe the input change event.

onBlurChangeHandler

onBlur prop to subscribe the input blur event.

refReact.Ref<any>

Input reference for hook form to register.

namestring

Input's name being registered.

Rules

  • It 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.

  • It 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 an undefined form value. If you want to prevent users from updating the input, you can use readOnly 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.

Input NameSubmit Result
register("firstName"){firstName: 'value'}
register("name.firstName"){name: { firstName: 'value' }}
register("name.firstName.0"){name: { firstName: [ 'value' ] }}
Register Options

By selecting the register option, the API table below will get updated.

NameDescriptionCode Examples
ref
React.Ref
React element ref
<input {...register("test")} />
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 errors object.
<input
  {...register("test", {
    required: true
  })}
/>
maxLength
number
The maximum length of the value to accept for this input.
<input
  {...register("test", {
      maxLength: 2
  })}
/>
minLength
number
The minimum length of the value to accept for this input.
<input
  {...register("test", {
    minLength: 1
  })}
/>
max
number
The maximum value to accept for this input.
<input
  type="number"
  {...register('test', {
    max: 3
  })}
/>
min
number
The minimum value to accept for this input.
<input
  type="number"
  {...register("test", {
    min: 3
  })}
/>
pattern
RegExp

The regex pattern for the input.

Note: A RegExp object with the /g flag keeps track of the lastIndex where a match occurred.

<input
  {...register("test", {
    pattern: /[A-Za-z]{3}/
  })}
/>
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.

Note: for object or array input data, it's recommend to use the validate function for validation as the other rules mostly apply to string, string[], number and boolean data type.

<input
  {...register("test", {
    validate: value => value === '1'
  })}
/>
// object of callback functions
<input
  {...register("test1", {
    validate: {
      positive: v => parseInt(v) > 0,
      lessThanTen: v => parseInt(v) < 10,
      checkUrl: async () => await fetch(),
    }
  })}
/>
valueAsNumber:
boolean

Returns a Number normally. If something goes wrong NaN will be returned.

  • valueAs process is happening before validation.

  • Only applies to text input.

  • Does not transform defaultValue ordefaultValues.
<input
  type="number"
  {...register("test", {
    valueAsNumber: true,
  })}
/>
valueAsDate:
boolean

Returns a Date object normally. If something goes wrong null will be returned.

  • valueAs process is happening before validation.

  • Only applies to text input.

  • Does not transform defaultValue ordefaultValues.
<input
  type="date"
  {...register("test", {
    valueAsDate: true,
  })}
/>
setValueAs:
<T>(value: any) => T

Return input value by running through the function.

  • valueAs process is happening before validation. Also, setValueAs is ignored if either valueAsNumber or valueAsDate are true.

  • Only applies to text input.

  • Does not transform defaultValue ordefaultValues.
<input
  type="number"
  {...register("test", {
    setValueAs: v => parseInt(v),
  })}
/>
disable
boolean = false
Set disable to true will lead input value to be undefined and input control to be disabled.
<input
  {...register("test", {
    disabled: true
  })}
/>
value
unknown

Set up value for the registered input.

register('firstName', { value: 'bill' })
shouldUnregister:
boolean

Input will be unregistered after unmount and defaultValues will be removed as well.

<input
  {...register("test", {
    shouldUnregister: true,
  })}
/>
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", { 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 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>
  );
}

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 });
            
const { onChange } = register('lastChange'); // this onChange method can update the input value

// This will work for React Native, except you can't reset input value
<TextInput onTextChange={onChange} />

Custom onChange, onBlur

When you want to combine with your onChange, onBlur, you can achieve by the following:

// onChange got overwrite by register method
<input onChange={handleChange} {...register('test')} />

// register's onChange got overwrite by register method
<input {...register('test')} onChange={handleChange}/>

const firstName = register('firstName', { required: true })
<input 
  onChange={(e) => {
    firstName.onChange(e); // method from hook form register
    handleChange(e); // your method
  }}
  onBlur={firstName.onBlur}
  ref={firstName.ref} 
/>

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 
  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>
));
Edit