Capítulo 31 de 39

Chapter 31: useFormContext

Core Idea

useFormContext() retrieves the full useForm() return value from React Context, avoiding prop-drilling in deeply nested form trees; it requires the tree to be wrapped in FormProvider.

Key Concepts

  • No arguments, returns UseFormReturn: same shape as calling useForm() directly.
  • Requires FormProvider: useFormContext only works inside a tree wrapped in <FormProvider {...methods}>.
  • Third generic: useFormContext<TFieldValues, TContext, TTransformedValues>() types a resolver's transformed output separately (since 7.44.0).
  • Prefer useFormState for subscribing to state values: formState from useFormContext() is wrapped in a Proxy that only tracks fields actually read during render; destructuring it and reading a property later (in a callback) or conditionally won't register a subscription, so the component silently won't re-render on change — use useFormState when you need to react to errors/isDirty/dirtyFields.

Code Examples

export default function App() {
  const methods = useForm()
  const { register, reset } = methods

  useEffect(() => { reset({ name: "data" }) }, [reset]) // never depend on `methods` itself

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <NestedInput />
      </form>
    </FormProvider>
  )
}

function NestedInput() {
  const { register } = useFormContext()
  return <input {...register("test")} />
}
  • What it demonstrates: a component several levels deep registering a field with zero props passed down.

Anti-patterns

  • Destructuring formState from useFormContext() and reading a property outside render (in a callback, or behind a condition): breaks the Proxy-based subscription tracking — use useFormState instead when the read isn't unconditional and at render time.

Key Takeaways

  1. useFormContext is the read side of the FormProvider pattern — always pair them.
  2. For any formState value read conditionally or inside a callback, use useFormState, not useFormContext().formState.

Connects To

  • formprovider: the write/host side of this pattern.
  • useformstate: the correct hook for subscribing to specific formState slices with proper Proxy tracking.