Capítulo 15 de 39
register(name, options?) connects an input to the form — returns { name, ref, onChange, onBlur, ...(progressive attrs) } to spread onto the element, and configures HTML-standard-based validation rules for it.
test.0.firstName), bracket syntax (test[0].firstName) doesn't work.register("test", {...}) again on the same name merges into the existing options — passing {} or undefined does not clear a previously set option; update the specific key instead (e.g. { required: false }).register("firstName") → { firstName: value }; register("name.firstName") → { name: { firstName: value } }; register("name.firstName.0") → nests into an array.mode, they don't block typing: required, min/max, minLength/maxLength, pattern are RHF-level rules, not native HTML attributes, unless progressive: true is set on useForm (then they're also reflected as real DOM attributes and on the returned object).true/undefined (valid), a string (error message), or false (generic error). Recommended over the other rules for object/array field values.setValueAs is ignored if either of the other two is true); none of them transform defaultValue/defaultValues.undefined and built-in validation rules are skipped entirely for that field.onChange/onBlur), also re-validate the listed fields — does not apply when validation is triggered manually via trigger().unregister — RHF doesn't do this for you (except when shouldUnregister: true is set globally or per-field).ref or _f — conflicts with RHF's internal type checks.<input {...register("firstName", { required: true })} placeholder="First name" />
<input {...register("lastName", { minLength: 2 })} placeholder="Last name" />
<input {...register("checkbox")} type="checkbox" value="A" />
<input {...register("radio")} type="radio" value="A" />
register works the same way across text, checkbox, and radio inputs — the value shape at submission depends on the input type, not on any extra config.<input
{...register("product", {
validate: {
checkAvailability: async (product, { category }) => {
if (!category) return "Choose a category"
if (!product) return "Specify your product"
return (await checkProduct(category, product)) || "There is no such product"
},
},
})}
/>
validate function reading a sibling field via the second argument.| Rule | Applies to | Notes |
|---|---|---|
required | any | for object/array values use validate instead |
minLength / maxLength | string-like | |
min / max | number-like | |
pattern | strings | a /g regex retains lastIndex state between calls |
validate | anything | function or named-function map; can be async, can read other field values |
valueAsNumber / valueAsDate / setValueAs | number/date/text inputs | pre-validation transforms, mutually exclusive |
disabled | any | value becomes undefined, skips built-in validation |
deps | any | cross-triggers re-validation of listed fields |
register("test[0].firstName") doesn't work — always dot syntax.{} or undefined to a second register call expecting it to clear prior options: options merge, they don't reset; explicitly override the specific key.name prop across renders: re-registers it as an entirely new field.unregister explicitly, or set shouldUnregister.register's validation rules run according to mode/reValidateMode — set progressive: true if you also want them as real HTML attributes.validate — the other rules are built for strings/numbers/booleans.unregister or shouldUnregister are the explicit opt-ins.useEffect).register.