When to use
- Creating or refactoring React forms.
- Using
useForm,register,handleSubmit, orformState. - Adding validation, schema resolvers, or typed form values.
- Integrating UI-library inputs with
Controller. - Building repeatable fields with
useFieldArray.
Goal
Use React Hook Form's uncontrolled-first model.
Prefer native inputs with register.
Use Controller only when a component cannot expose normal input props.
Rules
- Use
useForm<FormValues>()near the form boundary. - Set
defaultValuesfor every editable field. - Use
registerfor native inputs and ref-forwarding custom inputs. - Use
Controllerfor controlled third-party inputs. - Use
useControllerfor reusable field components. - Use
FormProvideranduseFormContextfor large nested forms. - Use
useFieldArrayfor repeatable rows. - Use a resolver for shared schema validation.
- Use
reset(newValues)when loaded data becomes the clean baseline. - Use
useWatchonly when one component needs another field value. - Do not pass both
registerandControllerto one field. - Do not mirror every input with local
useState.
Flow
- Inspect existing form conventions.
- Define or infer
FormValues. - Add
useForm<FormValues>()with defaults. - Register fields.
- Add validation rules or resolver.
- Render
formState.errors. - Submit with
handleSubmit(onSubmit).
Pattern
type FormValues = { email: string };
const {
register,
handleSubmit,
formState: { errors },
} = useForm<FormValues>({ defaultValues: { email: "" } });
return (
<form onSubmit={handleSubmit(save)}>
<input {...register("email", { required: "Email is required" })} />
{errors.email?.message ? <p role="alert">{errors.email.message}</p> : null}
<button type="submit">Save</button>
</form>
);
Controlled Inputs
Use Controller for MUI fields, React Select, date pickers, masked inputs, or custom controlled components.
Pass field.value, field.onChange, field.onBlur, and field.ref.
Use fieldState for field-level errors.
Schema Validation
Prefer Zod or existing project schema tooling for complex forms.
Infer FormValues from the schema.
Use schema coercion or valueAsNumber for non-string values.
Output
- Typed form values.
- Default values for each field.
- Field validation near rules or schema.
- User-safe validation messages.
- Clear submit path.
Reference
Read references/patterns.md for controlled inputs, nested forms, repeatable fields, async defaults, resolvers, or typed reusable fields.