Capítulo 1 de 39
React Hook Form is installed with a single package and wired into a form by calling useForm() and spreading register("fieldName") onto each input; validation, values, and errors all flow from that one hook call.
{ name, onChange, onBlur, ref } to spread onto the input.type and optional message.ref.@hookform/resolvers so validation is defined as a schema instead of per-field rules.import { useForm, SubmitHandler } from "react-hook-form"
type Inputs = { example: string; exampleRequired: string }
export default function App() {
const { register, handleSubmit, watch, formState: { errors } } = useForm<Inputs>()
const onSubmit: SubmitHandler<Inputs> = (data) => console.log(data)
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input defaultValue="test" {...register("example")} />
<input {...register("exampleRequired", { required: true })} />
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
)
}
errors off formState.| Validation rule | Purpose |
|---|---|
required | field must have a value |
min / max | numeric bounds |
minLength / maxLength | string length bounds |
pattern | regex the value must match |
validate | custom function (or map of functions) returning true/error message |
value instead of defaultValue: RHF is uncontrolled by default; setting value on a registered input fights the library and breaks the first keystroke.Controller: components without a forwarded ref (MUI Select, react-select) silently fail to register without it.register + handleSubmit + formState.errors is the whole core loop for a plain HTML form.resolver, replacing per-field rules.Controller (or useController) is the integration point for any input that can't take a raw ref.register, handleSubmit, watch, control, and formState.