jhipster 中的 ValidatedField,它使用 react-hook-form - 如何将其用作组件中的字段,即。不是 ValidatedForm 的直接后代?

ValidatedField in jhipster, that uses react-hook-form - how to use this as a field within a component ie. not direct descendant of ValidatedForm?

我有

 <ValidatedForm onSubmit={saveEntity}>
                {step1Questions && step1Questions.map((question, index) => <FormQuestion question={question} key={index} />)}
             

然后在 FormQuestion


const FormQuestion = ({ question }: FormQuestionProps) => {
  const { register } = useForm();
  switch (question.questionType) {
    case 'text':
      return (
        <ValidatedField
          label={question.questionText}
          id="questionnaire-'${question.questionName}'"
          name={question.questionName}
          data-cy={question.questionName}
          type="text"
        />
      );
    case 'radio':

但验证不起作用 - 在代码中的文档中它说 - " * 对于复杂的用例或嵌套的子项,使用 Reactstrap 表单元素或 ValidatedField 或 ValidatedInput 并传递来自 react-hook-form 的 useForm 钩子的方法和值

但它并没有真正说明哪些方法和值。如果我想在上面添加验证,我该怎么做?

我遇到过类似的问题。您可能想查看您是否有权访问 validated-form.tsx 文件,因为您可以在其中找到 ValidatedFormValidatedField 的代码。看看这些帮助我使用 useForm 钩子。

张贴在这里供参考


    export function ValidatedForm({ defaultValues, children, onSubmit, mode, ...rest }: ValidatedFormProps): JSX.Element {
      const {
        handleSubmit,
        register,
        reset,
        setValue,
        formState: { errors, touchedFields, dirtyFields },
      } = useForm({ mode: mode || 'onTouched', defaultValues });

      useEffect(() => {
        reset(defaultValues);
      }, [reset, defaultValues]);

      return (
        <Form onSubmit={handleSubmit(onSubmit)} {...rest}>
          {React.Children.map(children, (child: ReactElement) => {
            const type = child?.type as any;
            const isValidated =
              type && child?.props?.name && ['ValidatedField', 'ValidatedInput', 'ValidatedBlobField'].includes(type.displayName);

            if (isValidated) {
              const childName = child.props.name;
              const elem = {
                ...child.props,
                register: child.props.register || register,
                error: child.props.error || errors[childName],
                isTouched: typeof child.props.isTouched === 'undefined' ? touchedFields[childName] : child.props.isTouched,
                isDirty: typeof child.props.isDirty === 'undefined' ? dirtyFields[childName] : child.props.isDirty,
                key: childName,
              };
              if (type.displayName === 'ValidatedBlobField') {
                const defaultValue = defaultValues[childName];
                const defaultContentType = defaultValues[`${childName}ContentType`];
                elem.setValue = typeof child.props.setValue === 'undefined' ? setValue : child.props.setValue;
                elem.defaultValue = typeof child.props.defaultValue === 'undefined' ? defaultValue : child.props.defaultValue;
                elem.defaultContentType =
                  typeof child.props.defaultContentType === 'undefined' ? defaultContentType : child.props.defaultContentType;
              }
              return React.createElement(type, { ...elem });
            }
            return child;
          })}
        </Form>
      );
    }

回答

所以 ValidatedForm 查看它的子项并检查它是否是 ValidatedFieldValidatedInput 等。如果不是,那么它不会执行 useForm钩东西。在您的代码中,FormQuestion 是直接子项,因此它不会执行 useForm 操作。

相反,您必须手动完成。首先,去掉 ValidatedForm 并将其替换为 Form ,就像您在代码片段中看到的那样。然后,复制 useForm 代码并将其放入您的代码中,您可能需要进行一些小的调整。最重要的是,您需要在 ValidatedField 标签

中添加 register: register

所以最后,它应该看起来像

const {
        handleSubmit,
        register,
        reset,
        setValue,
        formState: { errors, touchedFields, dirtyFields },
      } = useForm({ mode: 'onTouched', defaultValues });

<Form onSubmit={handleSubmit(saveEntity)}>
                {step1Questions && step1Questions.map((question, index) => <FormQuestion question={question} key={index} />)}

const FormQuestion = ({ question }: FormQuestionProps) => {
  switch (question.questionType) {
    case 'text':
      return (
        <ValidatedField
          register: register
          label={question.questionText}
          id="questionnaire-'${question.questionName}'"
          name={question.questionName}
          data-cy={question.questionName}
          type="text"
        />
      );
    case 'radio':