Capítulo 39 de 39

Chapter 39: createFormControl

Core Idea

createFormControl(props) builds a form's entire state/subscription machinery outside of React — a formControl/control pair you can hand to useForm({ formControl }) or use directly (register, subscribe, etc.) without a FormProvider, useful for global/shared form state or subscribing to formState without triggering component re-renders.

Key Concepts

  • formControl: pass this into useForm({ formControl }) to connect a component tree to state that was created outside React.
  • control: the object to hand to useController, useFormState, useWatch directly — no Context/FormProvider needed.
  • subscribe: subscribe to formState/values updates with a callback, without causing any component to re-render.
  • Mutual exclusivity with FormProvider: use createFormControl OR the Context API (FormProvider), not both — wrapping createFormControl's props in a <FormProvider> is redundant since its methods are already usable directly.

Code Examples

const { formControl, control, handleSubmit, register } = createFormControl({
  mode: "onChange",
  defaultValues: { firstName: "Bill" },
})

function App() {
  useForm({ formControl })
  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <input {...register("name")} />
    </form>
  )
}

function ControlledInput() {
  // no FormProvider/context needed — `control` was created standalone
  const { field } = useController({ control, name: "firstName" })
  return <input {...field} />
}
  • What it demonstrates: control from createFormControl flows directly into useController/useFormState/useWatch in any component, without Context.

Reference Tables

Return fieldTypeDescription
formControlObjectpass into useForm({ formControl })
controlObjectpass into useController/useFormState/useWatch
subscribeFunctionsubscribe to formState updates without a render
...returnsFunctionsevery other useForm return method (register, handleSubmit, …)

Anti-patterns

  • Wrapping createFormControl's props in <FormProvider>: unnecessary — its methods (register, control, …) are already directly usable without a provider.

Key Takeaways

  1. createFormControl exists to build form state before/outside a React component tree, or to share one form's state across components without Context.
  2. subscribe is the render-free way to react to formState/value changes.
  3. Pick either createFormControl or FormProvider for a given form — not both.

Connects To

  • useform: createFormControl's props are UseFormProps, same as useForm.
  • formprovider: the Context-based alternative for sharing form state across a tree.
  • useform-subscribe: the render-free subscription API, also exposed here.