React Hook Form: How I Keep Complex Forms Sane
Forms get messy when rules live in ten places. I keep it strict: schema for validation, one place for change rules, and predictable Save behaviour.
The pattern: schema + watch + derived button state
import { useForm, useWatch } from "react-hook-form"
import { z } from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
const schema = z.object({
name: z.string().min(1),
status: z.enum(["draft", "active"]),
})
type FormValues = z.infer<typeof schema>
const form = useForm<FormValues>({
defaultValues,
resolver: zodResolver(schema),
mode: "onChange",
})
const values = useWatch({ control: form.control })
const canSave = form.formState.isValid && form.formState.isDirty
Rules I follow
reset(savedValues) so state is stable and predictable