#javascript #reactjs #forms #typescript #formik
#javascript #reactjs #формы #typescript #formik
Вопрос:
Я понимаю, что это может быть нестандартный вопрос или даже 2 в одном, но, пожалуйста, поверьте мне, когда я говорю, что на эти 2 нельзя ответить отдельно. Пожалуйста, имейте это в виду. Спасибо за ваше время..
Мой вопрос вращается вокруг конкретного сценария, с которым я в настоящее время сталкиваюсь. Я использую withFormik H.O.C, наряду с Yup, для обработки различных случаев в моих формах, таких как отправка, обработка ошибок и еще несколько в зависимости от ситуации.
Обычно моя ситуация с формой включает в себя режимы создания и редактирования.
onCreate => Передать значения по умолчанию и вызвать метод POST из моих сервисов.
onEdit => Заполнить значения текущими значениями элементов с сервера и вызвать метод PUT из служб.
Пример
const validationSchema = Yup.object().shape({
username: Yup.string('Provide a Username').required('Username is Required'),
email: Yup.string().email('Provide a Valid email Address'),
password: Yup.string('Provide a Password').required('Password is required'),
confirmPassword: Yup.string('Provide your password again')
.required('Password Confirmation is Required')
.oneOf([Yup.ref('password')], 'Passwords do not match'),
});
const EnchancedCreateUserForm = withFormik({
mapPropsToValues: ({
user = {
username: '',
email: '',
password: '',
confirmPassword: '',
}
}) => ({ ...user }),
validationSchema,
handleSubmit: (values, { props, setSubmitting }) => {
const { doSubmit, onSave, inEditMode } = props;
const saveUser = inEditMode ? updateUser : createUser;
return doSubmit(saveUser, values)
.then(() => {
setSubmitting(false);
onSave();
})
.catch(() => {
setSubmitting(false);
});
},
displayName: 'AddEditUser'
})(AddEditUser);
На самом деле это отлично работает для меня, поскольку мои формы создания и редактирования одинаковы. И здесь лежат мои 2 проблемы.
Текущая ситуация Моя текущая реализация формы имеет 2 представления. Одна унифицированная при создании с этими 4 полями и при редактировании, у меня есть 2 формы. Одна для passwordChange и одна для infoChange. Что заставляет меня сталкиваться со следующими проблемами.
Мне понадобились бы 3 схемы проверки формы (CREATE, EDIT-INFO, EDIT-PASSWORD). Я не уверен, что formik вообще поддерживает. Как именно я должен обрабатывать остальную функциональность, onSubmit, ErrorMessage как для ошибки поля, так и для statusError? Если бы вы действительно могли помочь мне найти способ атаки, это было бы здорово.
Я прочитал, что в validationSchema может быть передана функция, которая возвращает validationSchema, поэтому я сделал это, но это не работает:
const validationFullSchema = Yup.object().shape({
username: Yup.string('Provide a Username').required('Username is Required'),
email: Yup.string().email('Provide a Valid email Address'),
password: Yup.string('Provide a Password').required('Password is required'),
confirmPassword: Yup.string('Provide your password again')
.required('Password Confirmation is Required')
.oneOf([Yup.ref('password')], 'Passwords do not match'),
});
const validationEditSchema = Yup.object().shape({
username: Yup.string('Provide a Username').required('Username is Required'),
email: Yup.string().email('Provide a Valid email Address'),
});
const validationSchemaFn = () => {
If ( efitMode ) {
return validationCreateSchema
}
верните validationEditSchema
}
validationSchema: validationSchemaFn(),
// Which throws an error
// Failed to load app. Error: Cannot read property 'props' of undefined
Возможно, я делаю что-то неправильно, но я поместил это здесь на всякий случай.
Мое мнение по этому вопросу
- Создайте 2 компонента формы (PasswordFormComponent, InfoFormComponent) и оберните каждый из них с помощью H.O.C, предоставляя им независимый доступ к withFormik.
- Для CreateForm преобразуйте его в компонент контейнера, который отображает оба этих компонента
- Для редактирования вместо вызова всей формы, что в данный момент и происходит, вызывайте для каждой ситуации определенный компонент.
Что вы думаете о моем предложенном решении? Если вам это нравится, не могли бы вы, пожалуйста, улучшить это или помочь с некоторыми примерами кода, особенно в нескольких validationSchemas
проблемах. Спасибо!!
Ответ №1:
Вы должны создать только одну форму formik. и оттуда, где вы вызываете компонент формы, передайте действие как 1 для создания и 2 для редактирования. из props, если вы получаете 2, не отображайте компонент password. Остальное будет видно. используйте ту же схему проверки, укажите некоторые статические значения для пароля и подтвердите пароль в случае редактирования, чтобы ваша схема могла позволить вам отправить вашу форму. и просто измените тело запроса соответственно для create и edit.