React使用react-hook-form提交表单无法获取错误信息的解决方法
问题原因及修复方案
你的代码问题在于**Form组件和Input组件各自调用了useForm(),生成了两个完全独立的表单状态实例**。Input里注册的字段属于它自己的表单实例,Form组件的实例根本感知不到这个字段的存在,所以提交时不会触发验证,自然也获取不到错误信息。
下面提供两种可靠的修复方式:
方式一:通过Props传递register函数
修改Form组件,将自身表单实例的register传递给子组件;同时修改Input组件,不再单独调用useForm(),而是使用父组件传递过来的register:
import React from 'react'; import { useForm } from 'react-hook-form'; const Form = ({ onSubmit, children }) => { const { handleSubmit, formState: { errors }, register } = useForm(); console.log(errors, 'errrerrr'); // 为所有子元素注入register属性 const childrenWithRegister = React.Children.map(children, child => { if (React.isValidElement(child)) { return React.cloneElement(child, { register }); } return child; }); return ( <form onSubmit={handleSubmit(onSubmit)}>{childrenWithRegister}</form> ); }; const Input = ({ fProps, register, ...rest }) => { return <input {...rest} {...register('name', fProps)} />; }; export default function App() { const onSubmit = data => console.log(data, 'details'); return ( <Form onSubmit={onSubmit}> <Input name='name' type="text" placeholder="First name" fProps={{ required: 'please add data', minLength: 1 }}/> <input type="submit" /> </Form> ); }
注意:你原来用的
min是错误的,文本长度验证应该用minLength,min是针对数字类型字段的。
方式二:使用FormProvider和useFormContext
利用react-hook-form的上下文API,让子组件共享同一个表单实例:
import React from 'react'; import { useForm, FormProvider, useFormContext } from 'react-hook-form'; const Form = ({ onSubmit, children }) => { const methods = useForm(); const { handleSubmit, formState: { errors } } = methods; console.log(errors, 'errrerrr'); return ( <FormProvider {...methods}> <form onSubmit={handleSubmit(onSubmit)}>{children}</form> </FormProvider> ); }; const Input = ({ fProps, ...rest }) => { const { register } = useFormContext(); return <input {...rest} {...register('name', fProps)} />; }; export default function App() { const onSubmit = data => console.log(data, 'details'); return ( <Form onSubmit={onSubmit}> <Input name='name' type="text" placeholder="First name" fProps={{ required: 'please add data', minLength: 1 }}/> <input type="submit" /> </Form> ); }
这两种方式都能让Input和Form共享同一个表单状态,提交时会触发验证,Form组件里的errors就能正确获取到验证错误了。
内容的提问来源于stack exchange,提问作者Asking
相关产品推荐
相关产品推荐

