React Hook Form is the most performant form library in React — and its API goes way deeper than useForm and register.
The Controller API: Controlled Components Made Easy
import { useForm, Controller } from "react-hook-form";
import { DatePicker } from "some-ui-lib";
function MyForm() {
const { control, handleSubmit } = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="birthdate"
control={control}
rules={{ required: "Date is required" }}
render={({ field, fieldState }) => (
<>
<DatePicker {...field} />
{fieldState.error && <span>{fieldState.error.message}</span>}
</>
)}
/>
</form>
);
}
The FormProvider API: Cross-Component Forms
import { useForm, FormProvider, useFormContext } from "react-hook-form";
function ParentForm() {
const methods = useForm();
return (
<FormProvider {...methods}>
<NestedInput />
<DeepNestedSection />
</FormProvider>
);
}
function NestedInput() {
const { register } = useFormContext(); // Access form from anywhere!
return <input {...register("nested.field")} />;
}
useFieldArray: Dynamic Form Fields
import { useForm, useFieldArray } from "react-hook-form";
function DynamicForm() {
const { control, register } = useForm({
defaultValues: { items: [{ name: "" }] }
});
const { fields, append, remove, move } = useFieldArray({
control,
name: "items"
});
return (
<form>
{fields.map((field, index) => (
<div key={field.id}>
<input {...register(`items.${index}.name`)} />
<button onClick={() => remove(index)}>Remove</button>
</div>
))}
<button onClick={() => append({ name: "" })}>Add Item</button>
</form>
);
}
Zod Integration: Schema-First Validation
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
const schema = z.object({
email: z.string().email("Invalid email"),
password: z.string().min(8, "Min 8 characters"),
confirmPassword: z.string()
}).refine((data) => data.password === data.confirmPassword, {
message: "Passwords don match",
path: ["confirmPassword"]
});
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema)
});
useWatch: Performant Field Subscriptions
import { useWatch } from "react-hook-form";
function PricePreview({ control }) {
const price = useWatch({ control, name: "price", defaultValue: 0 });
const quantity = useWatch({ control, name: "quantity", defaultValue: 1 });
return <p>Total: ${price * quantity}</p>; // Only re-renders when price/quantity change
}
Why It Beats Formik
| Feature | React Hook Form | Formik |
|---|---|---|
| Re-renders | Minimal (uncontrolled) | Every keystroke |
| Bundle size | 8.6KB | 44KB |
| TypeScript | First-class | Bolt-on |
| Performance | O(1) | O(n) fields |
Building data-driven forms? My Apify scraping tools can feed structured data directly into your React forms.
Need a custom data solution? Email spinov001@gmail.com
Top comments (0)