React结合react-hook-form使用模板模式访问父表单methods的问题
React结合react-hook-form使用模板模式访问父表单methods的问题
嘿,我看你现在的问题是想在ContactForm里拿到BaseForm中初始化的react-hook-form的methods,但直接用useFormContext没效果对吧?其实核心原因很简单:useFormContext只能在FormProvider包裹的组件树范围内生效,而你的ContactForm组件本身是在BaseForm的外层,不在FormProvider的覆盖范围内,所以肯定拿不到。
给你两种实用的解决方案,你可以根据自己的需求选:
方案一:在提交回调中直接传入methods
这种方式最简单,不需要改太多结构,只需要调整BaseForm的onSubmit逻辑,把methods作为参数传给提交函数就行:
首先修改BaseForm.tsx,让onSubmit能接收data和methods:
import { useForm, FormProvider, UseFormReturn } from "react-hook-form" export const BaseForm = ({ children, // (methods: UseFormReturn<any>) => React.ReactNode onSubmit, // (data: any, methods: UseFormReturn<any>) => void }) => { const methods = useForm() const { handleSubmit } = methods // 包装提交函数,把methods也传进去 const handleFormSubmit = (data: any) => { onSubmit(data, methods) } return ( <FormProvider {...methods}> <form onSubmit={handleSubmit(handleFormSubmit)} noValidate={true}> {children(methods)} </form> </FormProvider> ) }
然后在Child.tsx里,就能直接在onSubmit中拿到methods了:
export const ContactForm = () => { const onSubmit = (data: any, methods) => { // 这里可以直接用methods的所有方法,比如重置表单 methods.reset() // 你的其他提交逻辑... } return ( <BaseForm onSubmit={onSubmit}> {(methods) => ( <> <TextField {...methods.register("field1")} /> {/* 其他输入字段... */} </> )} </BaseForm> ) }
方案二:拆分组件,让useFormContext处于作用域内
如果你一定要在组件级别用useFormContext,可以把表单的输入字段拆成一个独立的子组件,这个子组件会被FormProvider包裹,自然就能拿到上下文了:
import { useFormContext } from "react-hook-form" // 这个组件在FormProvider范围内,所以能拿到上下文 const ContactFormFields = () => { const methods = useFormContext() // 现在可以正常使用了! // 这里也可以直接调用methods的方法,比如重置 const handleReset = () => { methods.reset() } return ( <> <TextField {...methods.register("field1")} /> <button type="button" onClick={handleReset}>重置</button> {/* 其他输入字段... */} </> ) } export const ContactForm = () => { const onSubmit = (data: any) => { // 你的提交逻辑... } return ( <BaseForm onSubmit={onSubmit}> {(methods) => <ContactFormFields />} </BaseForm> ) }
这两种方案都能解决你的问题,第一种更适合需要在提交时操作methods的场景,第二种适合需要在表单字段组件里直接调用methods方法的场景。
备注:内容来源于stack exchange,提问作者renatodamas
相关产品推荐
相关产品推荐

