Capítulo 38 de 39
FormProvider puts every useForm() method/state on React Context, so any descendant can call useFormContext() and get register/control/handleSubmit/etc. without prop drilling.
{...methods} (the full useForm() return) as props and hosts them on context.useForm() returned at the provider.FormProviders means an inner useFormContext() only sees the innermost form, silently breaking registration/validation for consumers expecting the outer form.FormProviderProps<TFieldValues, TContext, TTransformedValues> (since 7.44.0) types a resolver's transformed output through the provider.export default function App() {
const methods = useForm()
const { register, reset } = methods
useEffect(() => {
reset({ name: "data" })
}, [reset]) // never put `methods` itself as a dependency
return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NestedInput />
<input {...register("name")} />
</form>
</FormProvider>
)
}
function NestedInput() {
const { register } = useFormContext() // retrieve all hook methods
return <input {...register("test")} />
}
NestedInput registers a field without any prop being passed to it — only useFormContext().FormProvider components: consumers inside the inner provider silently bind to the wrong form.methods (the whole object) in a useEffect dependency array: it's a new reference-shape object each render conceptually; depend on the specific method (reset) instead.FormProvider + useFormContext is the standard fix for prop-drilling register/control through deep component trees.FormProviders — context doesn't merge, so the inner one wins entirely for its subtree.createFormControl's control/methods are a Context-free alternative when you don't want the re-render cost of a Provider subtree.FormProvider's props.ConnectForm/FormProviderPerformance recipes build directly on this pattern.