Условная проверка нескольких полей с помощью Yup

#formik #yup

Вопрос:

У меня есть 3 поля ввода (имя, идентификатор и почтовый индекс), и я использую formik вместе с Yup для проверки.

Чего я хочу добиться здесь, так это сопоставить каждому входному полю известную комбинацию имени, идентификатора и почтового индекса (у меня есть предопределенное значение по умолчанию для идентификатора, имени, почтового индекса).

И если значения, введенные во всех 3 полях ввода, точно совпадают со значениями по умолчанию имени, идентификатора и почтового индекса, то я должен показать ошибку formik в каждом из полей(*что-то вроде по умолчанию не разрешено). Если одно из этих полей отличается от значений по умолчанию, не показывайте ошибку ни в одном из полей.

Например, если мои значения по умолчанию для каждого поля name=»testName», id=»TestID», почтовый индекс=»testPostCode», показывать ошибку проверки в каждом поле только в том случае, если все 3 входных значения совпадают со значениями по умолчанию.

Вот что у меня сейчас есть:

 const defaultValues = {
  name: 'testName',
  id: 'testID',
  postCode: 'testPostCode'
}

const YUP_STRING = Yup.string().ensure().trim();

const validationSchema = yup.object().shape({
   name: YUP_STRING.required('required'),
   id: YUP_STRING.required('required'),
   postcode: YUP_STRING.required('required'),
})
 

Я перепробовал несколько вариантов, но здесь ничего не сработало. Кто-нибудь может помочь мне найти решение для этого?

Ответ №1:

Вы можете сделать что-то вроде <Field validate={(value)=>validate(value,values)} name="name" type="text" />

Более подробно..

 <Formik
     initialValues={defaultValues}
     onSubmit={values => alert(JSON.stringify(values)}
   >
     {({ errors, touched, values }) => (
       <Form>
         <Field validate={(value) => validate(value, values)} name="name" type="text" />
         {errors.name amp;amp; touched.name ? <div>{errors.name}</div> : null}
         <button type="submit">Submit</button>
       </Form>
     )}
</Formik>
 

И определите функцию проверки как

 const validate = (value, values) => {
  if(values === defaultValues){
    return "Default Values not allowed"
  } else return undefined
}
 

Или, если вы хотите сделать это с помощью validationSchema, вы можете что-то сделать, например, добавив test функцию в каждое поле, я сделал это только для имени:

 const validationSchema = yup.object().shape({
   name: YUP_STRING.required('required')
         .test('name', "No default please", function (item) {
                   const currentValues = {
                       name: this.parent.name,
                       id: this.parent.id,
                       postCode: this.parent.postCode
                     }
                   return !(currentValues === defaultValues)
              }
          ),
   id: YUP_STRING.required('required'),
   postcode: YUP_STRING.required('required'),
})
 

Нет функции со стрелками, которую можно использовать this

Комментарии:

1. Это кажется немного сложным, есть ли способ сделать это, добавив некоторые дополнительные тесты в объект validationSchema, который у меня есть?

2. Я так не думаю, афаик, вы не можете получить доступ ко всем значениям по умолчанию из схемы проверки yup. Вы можете настроить этот способ, о котором я упоминал выше, чтобы сделать его более модульным для каждого поля или формы.

3. Я могу получить доступ к значениям по умолчанию внутри схемы проверки здесь. Вот почему я только что объявил об этом в той же области.