JHipster中ValidatedField非ValidatedForm直接子组件的react-hook-form校验实现方法
嵌套子组件场景下表单校验失效的解决方案
问题根因
校验失效的核心原因是:父组件<ValidatedForm>绑定的react-hook-form实例,和子组件<FormQuestion>内单独调用useForm()生成的是完全独立的两个实例,数据、校验规则、错误状态完全不互通,导致父表单无法识别子组件内的表单项。
具体修改步骤
1. 父组件层统一初始化useForm实例
父组件内显式初始化useForm,将返回的方法绑定到<ValidatedForm>,同时透传给子组件<FormQuestion>:
// 父组件顶部导入useForm import { useForm } from 'react-hook-form'; // 父组件内部初始化表单实例 const { register, control, handleSubmit, formState: { errors } } = useForm<你的表单TS类型>(); // 渲染部分修改如下 <ValidatedForm onSubmit={handleSubmit(saveEntity)} control={control} errors={errors}> {step1Questions?.map((question, index) => ( <FormQuestion question={question} key={index} register={register} errors={errors} control={control} /> ))} </ValidatedForm>
2. 子组件删除独立的useForm调用,接收父组件透传的表单方法
修改子组件的入参,直接使用父组件传下来的表单方法绑定表单项:
// 先修改子组件Props类型定义,新增表单相关属性 type FormQuestionProps = { question: 你的问题配置TS类型; register: UseFormRegister<你的表单TS类型>; errors: FieldErrors<你的表单TS类型>; control: Control<你的表单TS类型>; } const FormQuestion = ({ question, register, errors, control }: FormQuestionProps) => { switch (question.questionType) { case 'text': return ( <ValidatedField label={question.questionText} id={`questionnaire-${question.questionName}`} name={question.questionName} data-cy={question.questionName} type="text" // 绑定父组件传过来的register,可在这里配置校验规则 {...register(question.questionName, { required: '该问题为必填项', // 可继续添加其他校验规则:minLength、maxLength、pattern等 })} // 绑定对应字段的错误提示 error={errors[question.questionName]?.message as string} /> ); case 'radio': // 单选等其他类型表单项同理,绑定register和error属性即可 // 其余case省略 } }
补充说明
- 如果你使用的
<ValidatedField>已经内置了register处理逻辑,不需要手动绑定,只需给组件传入control={control}属性即可完成关联。 - 所有校验规则都可以在
register的第二个参数中配置,错误状态会自动同步到父组件的errors对象中。
内容的提问来源于stack exchange,提问作者cordial
相关产品推荐
相关产品推荐

