16

我在 reactjs 中使用 formik 进行表单管理,我有一个关于 yup 验证的问题。

我有两个字段,一个是选择国家的选择控件,另一个是邮政编码。

在国家/地区数组中,我们有验证邮政编码的正则表达式,其想法是使用当前所选国家的正则表达式验证输入的邮政编码,有人可以提供有关如何执行此操作的线索。

4

7 回答 7

30

需要数值不能高于其他两个字段值的乘积的字段示例

const validationSchema = Yup.object().shape({
    num1: Yup.number().positive().required('This field is required.'),
    num2: Yup.number().positive().required('This field is required.'),
    num3: Yup.number().positive().required('This field is required.')
       .when(['num1', 'num2'], (num1, num2, schema) => {
            return num1 > 0 && num2 > 0 ? schema.max(num1 / num2) : schema.max(0);
        })
});

于 2020-06-11T19:48:18.650 回答
6

下面是一个将日期选择器的结束日期强制为after开始日期的示例:

const schema = Yup.object().shape({
    start_date: Yup.date()
        .typeError('Start Date is required')
        .required('Start Date is required'),
    end_date: Yup.date()
        .typeError('End Date is required')
        .required('End Date is required')
        .when('start_date', (start_date) => {
            if (start_date) {
                return Yup.date()
                    .min(start_date, 'End Date must be after Start Date')
                    .typeError('End Date is required')
            }
        }),
})

需要if在表单加载时放入语句以正确验证,并且还需要typeError在选择开始日期但尚未结束日期时放入规则以正确验证。

重要的是你可以看到when; 第一个参数是要检查的字段,第二个参数是返回 Yup 验证对象的验证函数。

我试图只返回 true 或 false,但它似乎会抛出错误,所以它比纯粹的验证函数要复杂一些。

于 2021-08-04T17:00:40.603 回答
4
let schema = object({
  isBig: boolean(),
  count: number()
    .when('isBig', {
      is: true, // alternatively: (val) => val == true
      then: yup.number().min(5),
      otherwise: yup.number().min(0),
    })
});
于 2020-05-18T15:07:12.003 回答
4

使用.when()并传递一个函数,该函数根据国家/地区的值返回邮政编码的模式。

于 2018-04-20T10:13:35.227 回答
3

我有同样的问题。我是一个能够用来when解决它的。

import { object, string } from 'yup';

const validCountries = ['US', 'CA'];

const zipRegexes = {
    US: /^\d{5}(?:-?\d{4})?$/,
    CA: /^[ABCEGHJKLMNPRSTVXY]\d[A-Z]\d[A-Z]\d$/
};

const addressSchema = object().shape({
    country: string()
        .oneOf(validCountries, 'Please select a country from the list above')
        .required('Please select a country from the list above'),
    /* Other fields
    .
    .
    .
    */
    zip: string()
        .trim()
        .required('Required')
        .transform(value => value.toUpperCase())
        .when('country', (country, schema) => {
            if (
                string()
                    .oneOf(validCountries)
                    .required()
                    .isValid(country)
            ) {
                return schema.matches(
                    zipRegexes[country],
                    `not a valid ${country} zip code`
                );
            }

            return schema;
        })
});
于 2020-08-17T20:33:46.977 回答
3

使用 Yup test() 使用其他表单字段的值进行验证。

您可以通过解构父类来访问任何表单字段的值 const { country } = this.parent;

const yup = require("yup");

const schema = yup.object({
  country: yup.object().required("This field is required"),
  zipcode: yup
    .string()
    .required("This field is required")
    .test("is-right-zipcode", "Invalid zipcode", function(code) {
      const { country } = this.parent;
      return code.match(country.regex);
    })
});
于 2021-09-13T13:37:34.520 回答
0

您可以根据字段数组进行条件验证。以下示例仅在未指定field6至少一项时才需要。field1 - field5

let schema = object({
  field1: Yup.bool(),
  field2: Yup.bool(),
  field3: Yup.bool(),
  field4: Yup.bool(),
  field5: Yup.bool(),
  field6: Yup.bool().when(
    [
      'field1',
      'field2',
      'field3',
      'field4',
      'field5',
    ],
    {
      is: (...fields) => fields.some(Boolean),
      then: Yup.bool().notRequired(),
      otherwise: Yup.bool().required(),
    }
  ),
});
于 2021-10-01T14:57:38.713 回答