#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':