javascript 使用Yup和Formik进行条件验证

pobjuy32  于 2023-03-16  发布在  Java
关注(0)|答案(5)|浏览(156)

下面是我的验证模式:

const validationSchema = Yup.object().shape({
      person: Yup.object().shape({
        name: Yup.string().required('Field is required'),
        surname: Yup.string().required('Field is required'),
        middleName: Yup.string().required('Field is required'),
        email: Yup.string()
          .email('Wrong e-mail format')
          .required('Field is required')
      }),
      company: Yup.object().shape({
        name: Yup.string().required('Field is required'),
        address: Yup.string().required('Field is required'),
        email: Yup.string()
          .email('Wrong e-mail format')
          .required('Field is required')
      })
    });

React状态中还有两个变量:isPersonisCompany,如何使校验有条件地工作,例如如果isPerson为真,则需要对validationSchema中的person进行校验?

sqyvllje

sqyvllje1#

更新答复:2023.
你可以用Yup条件

const validationSchema = Yup.object().shape({

      isCompany: Yup.boolean(),
      companyName: Yup.string().when('isCompany', {
        is: true,
        then: Yup.string().required('Field is required')
      }),
      companyAddress: Yup.string().when('isCompany', {
        is: (isCompany) => true,//just an e.g. you can return a function
        then: Yup.string().required('Field is required'),
        otherwise: Yup.string()
      }),
      // test a unconventional type
      logo: Yup.mixed()
       .test('file_size', 'error: file size exceeds!', (files, context) => {
         return filesIsValid(files) ? files[0].size <= 10000 : true
    // note here finally Im returning true, you can use context?.createError() but it will void .isNotReuired() 
// meaning even if you keep this field option your form will be still invalid 
       })
       .test('file_type', 'error msg: file type must match', () => )
    });

并确保相应地更新你的表格。我希望你明白这一点...

uqjltbpv

uqjltbpv2#

您可以像任何其他对象一样有条件地添加到验证方案中:

let validationShape = {
  company: Yup.object().shape({
    name: Yup.string().required('Field is required'),
    address: Yup.string().required('Field is required'),
    email: Yup.string()
      .email('Wrong e-mail format')
      .required('Field is required')
  })
};

if (this.state.isPerson) {
  validationShape.person = Yup.object().shape({
    name: Yup.string().required('Field is required'),
    surname: Yup.string().required('Field is required'),
    middleName: Yup.string().required('Field is required'),
    email: Yup.string()
      .email('Wrong e-mail format')
      .required('Field is required');
}

const validationSchema = Yup.object().shape(validationShape);
ssgvzors

ssgvzors3#

* YUP条件性确认 *:

当**时,**可以做的各种验证如下:

1.单值,简单条件:

规则:* 仅当isPerson为true时才请求personName。*

personName : Yup.string().when('isPerson', {
is: true, 
then: Yup.string().required('Field is required'),
otherwise: Yup.string(),
})

2.单值,复杂条件:

规则:* 当company是“IT”时,仅要求输入personName。*

personName : Yup.string().when('company', {
is: (company)=> company==='IT', 
then: Yup.string().required('Field is required'),
otherwise: Yup.string(),
})

3.多值、复杂条件:

规则:* 仅当company为“IT”且person有效时才要求提供personName。*

personName : Yup.string().when(['company', 'isPerson'], {
is: (company,isPerson)=> company==='IT'&& isPerson, 
then: Yup.string().required('Field is required'),
otherwise: Yup.string(),
})
enxuqcxy

enxuqcxy4#

虽然这个公认的解决方案是可行的,但它有一个问题--需要验证的字段中有两个是公共的,必须重复。在我的例子中,我的大多数字段都是公共的,只有2-4个异常值。
这里有另一个解决方案:
1.分别定义每个模式-即3个模式- commonSchema用于公共字段,personSchema用于个人特定字段,companySchema用于公司特定字段。
1.根据状态合并方案

const validationSchema = isPerson 
                        ? commonSchema.concat(personSchema)
                        : commonSchema.concat(companySchema)

有关“concat”的详细信息,请参阅github上的yup文档。

ffx8fchx

ffx8fchx5#

email: Yup.string()
                    .when(['showEmail', 'anotherField'], {
                        is: (showEmail, anotherField) => {
                            return (showEmail && anotherField);
                        },
                        then: Yup.string().required('Must enter email address')
                    }),

也可以使用多个字段进行验证。

相关问题