Skip to content

Hooks ​

Every React hook formstand exports. For the imperative surface these wrap, see createForm and Form.

React hooks ​

HookSignatureNotes
useFormuseForm(schema, options): Form<TSchema>lazy-creates a form held for the component's lifetime; schema and option changes after mount are ignored (warned once)
useFielduseField(form, path, options?): UseFieldReturn<V>one field's slice plus helpers. path may be a selector (state) => string, which returns UseFieldReturn<unknown>; options: { debounceMs?: number } debounces triggered validation. An explicit type argument on a schema-typed form is a readable compile error, because the value type infers from the path (see Typed paths)
useFieldArrayuseFieldArray(form, path): UseFieldArrayReturn<TItem>, with TItem inferred from the schema through the path (explicit <TItem> only for schema-less FieldFormApi forms)array ops plus stable ids; see Field arrays. An explicit <TItem> on a schema-typed form is a readable compile error (see Typed paths)
useVariantFielduseVariantField(form, unionPath, field): UseFieldReturn<V | undefined>binds a variant-only field of a discriminated union, since FieldPath exposes only common keys; field may be a dotted sub-path into a variant-only container ("billing.zip", "span.0"). See Discriminated unions. An explicit type argument on a schema-typed form is a readable compile error, because the variant value infers from the union path and field (see Typed paths)
useFormSelectoruseFormSelector(form, selector): Uselector-style subscription over FormState
useFormSelectorShallowuseFormSelectorShallow(form, selector): Ushallow-compared variant, required for object or array returning selectors
useFormValuesuseFormValues(form): z.input<TSchema>the whole values object, reactively. Sugar for useFormSelector(form, (s) => s.values). Reference-compared (values are replaced immutably), so it re-renders exactly when some value changes and never on touched or error churn. Reach for it when rendering is driven by values, such as a live map or preview. Structural FormStateApi forms read unknown
useFormErroruseFormError(form): readonly string[] | undefinedshortcut for the root "" error
useIsDirtyuseIsDirty(form, path?): booleanany field dirty (derived); a typed path scopes it to that subtree, so "shipping" covers shipping.city
useIsValiduseIsValid(form, path?): booleanno errors currently in the merged map, which is not the same as a fresh validation; a typed path scopes it to errors at or under that path
useIsSubmittinguseIsSubmitting(form): booleanstate.isSubmitting
useMaskedInputuseMaskedInput(field, { parse, format }): MaskedInputBindingthe raw-text editing pattern behind useNumberInput, generalized: partial entries stay visible without touching the form, parses push immediately, blur snaps to format(value). See Masked and formatted inputs
useFormStepsuseFormSteps(form, steps): UseFormStepsReturnthe wizard hook: per-step validation scopes over one form — next() gates on the current step's fields validating clean (errored fields marked touched like a failed submit), back() never validates, forward goTo() lands on the first failing step, steps is live per-step status. See Multi-step forms
useFormActionuseFormAction(form, onValid, options?): (formData: FormData) => Promise<void>the React 19 <form action={...}> bridge: validates first, then calls onValid(data, formData) with parsed z.output data under the full submit lifecycle; options: { onInvalid?, onError? } mirror handleSubmit. Reference-stable across renders. See SSR & Next.js
useFormActionStateuseFormActionState(form, action, initialState, options?): [state, formAction, isPending]useActionState with schema-validated data: action(prevState, data, formData) runs only when validation passes; invalid, skipped, and throwing submissions keep the previous state (field errors live in the form store). A "use server" function slots in as action
useSubmitCountuseSubmitCount(form): numberstate.submitCount
createFormContextcreateFormContext<TSchema>(): { Provider, useFormContext }typed context factory for prop-drilling-free forms
createFormHookscreateFormHooks(form, name?): FormHooksevery hook pre-wired to one form, with the name baked into the hook names ("invoice" gives you useInvoiceField and friends). This is the provider-free way to share a module-singleton form; see State

The pre-0.2 names useFormState and useFormStateShallow were renamed to useFormSelector and useFormSelectorShallow, because React DOM ships its own deprecated useFormState and auto-imports kept grabbing the wrong one. The deprecated aliases were removed in 0.4.0.

UseFieldReturn<TValue> ​

FieldTypeNotes
pathstringthe resolved path, used as the input's name
valueTValuetyped via FieldValue when the form carries a schema
initialValueTValuethe initialValues slice dirty compares against
emptyValuenull | undefinedwhat a cleared input writes back, introspected from the zod schema (.nullable() gives null, .optional() gives undefined), with an initial-value fallback for schema-less forms
clearablebooleanwhether the schema accepts that emptyValue (optional, nullable, or defaulted); the text and select bindings write emptyValue on clear only when true, so a required string cleared to "" stays ""
errorreadonly string[] | undefinedfrom the merged error map
touched / dirty / isValidatingboolean
setValue(v)writes the value and triggers mode-appropriate validation
setTouched(touched?)
setError(errors)writes the server channel at this path; takes a single string or a readonly string[], like form.setError
clearError()clearErrors(path), covering both channels at this path and its descendants
validate() / validateAsync()field-scoped validation
onBlur()marks touched and triggers mode-appropriate validation

UseFieldArrayReturn<TItem> ​

FieldType
fieldsreadonly { id: string; value: TItem }[], where id is your React key
itemsreadonly TItem[]
lengthnumber
errorreadonly string[] | undefined, the array-level error
push(item) / remove(index) / insert(index, item) / move(from, to) / swap(a, b)wrappers over the form's array ops

Built on zod and zustand. Released under the MIT License.