Проверенное поле в jhipster, которое использует форму реакции-крючка-как использовать это в качестве поля в компоненте ie. не прямой потомок ValidatedForm?

#reactjs #jhipster #react-hook-form

Вопрос:

У меня есть

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

а затем в форме вопроса

 
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- useForm hook».

Но на самом деле не говорится, какие методы и ценности. Если бы я хотел добавить проверку к вышесказанному, как бы я это сделал?

Ответ №1:

Я боролся с чем-то подобным. Возможно, вам захочется узнать, есть ли у вас доступ к validated-form.tsx файлу, потому что именно здесь вы найдете код для ValidatedForm и ValidatedField . Взглянув на них, я смог воспользоваться 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 amp;amp; child?.props?.name amp;amp; ['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 смотрит на своих детей и проверяет, является ли это a ValidatedField или ValidatedInput и т. Д. Если это не так, то он не делает useForm ничего плохого. В вашем коде FormQuestion это непосредственный ребенок, и поэтому он ничего не useForm делает.

Вместо этого вам придется сделать это вручную. Во-первых, избавьтесь от ValidatedForm него и замените его на Form то, что вы видите в фрагменте кода. Затем скопируйте useForm код и поместите его в свой код, вам, вероятно, придется внести небольшие коррективы. Самое главное, вы захотите добавить register: register внутри ValidatedField свой тег

Так что, в конце концов, это должно выглядеть примерно так

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

<Form onSubmit={handleSubmit(saveEntity)}>
                {step1Questions amp;amp; 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':