| name | react-hook-form |
| description | Performant, flexible forms with minimal re-renders using React Hook Form |
| layer | domain |
| category | forms |
| triggers | ["react hook form","useForm","useFieldArray","hookform","rhf"] |
| inputs | [{"form_requirements":"Fields, validation rules, submission behavior"},{"ui_library":"Controlled components in use (Select, DatePicker, etc.)"}] |
| outputs | [{"form_implementation":"useForm setup with validation and submission"},{"schema":"Zod schema with @hookform/resolvers integration"}] |
| linksTo | ["react","forms","zod","typescript-frontend"] |
| linkedFrom | ["forms","react","nextjs"] |
| riskLevel | low |
React Hook Form
Performant, flexible forms with minimal re-renders. Embraces uncontrolled inputs by default and isolates component re-renders for optimal performance.
When to Use
- Forms with 3+ fields where re-render performance matters
- Complex validation (async, cross-field, conditional)
- Dynamic fields (add/remove rows) or multi-step forms
- Integration with controlled UI libraries (Radix, MUI, Headless UI)
Key Patterns
useForm hook -- register, handleSubmit, watch, formState (errors, isSubmitting, isDirty):
const { register, handleSubmit, watch, formState: { errors, isSubmitting } } = useForm<T>({
resolver: zodResolver(schema), defaultValues: { ... },
mode: 'onBlur',
});
Zod integration via @hookform/resolvers:
import { zodResolver } from '@hookform/resolvers/zod';
const form = useForm({ resolver: zodResolver(mySchema) });
Controller for controlled components (Select, DatePicker, etc.):
<Controller name="role" control={control} render={({ field }) => (
<Select onValueChange={field.onChange} value={field.value}>{/* options */}</Select>
)} />