Formik | Как использовать несколько схем проверки и отображать разделенные представления для формы

#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.