Formik + 是的:如何验证位置模式,其中字段(国家、州、城市)不是强制性的,但如果填写了一个,则应填写每个字段?

Formik + yup: how to validate a location schema where the fields(country, state, city) are not mandatory, but if one is filled, each should be filled?

我有以下架构

validationSchema={yup.object().shape({
  firstName: yup
    .string()
    .required("Name cannot be empty")
    .matches(NAME_REGEX, "Name can only contain english characters"),
  lastName: yup
    .string()
    .required("Name cannot be empty")
    .matches(NAME_REGEX, "Name can only contain english characters"),
  location: yup
    .object()
    .nullable()
    .shape({
      country: yup.string().required(),
      state: yup.string().required(),
      city: yup.string().required()
    })
})}

firstNamelastName 的验证工作正常,但我不知道如何验证 location
要求location完全不需要填写。但是如果有一个(country/state,city)的字段被填了,那么三个都必须填。全部或 none.

尽管我尝试按上述方式验证它,但它不起作用。

另一个验证要求是:这些值是 select 从 select html 元素编辑的,其中第一个 <option><option key={0}>-select-</option>。所以,我不希望我的用户也 select 这个选项。截至目前,我正在通过检查值在 onSubmit 中处理它,如果它们包含 -select- 那么这些值将不会被考虑并将被现有值替换。

更新:
location 永远不能为空。如果用户没有设置任何位置字段,那么 location 也将是:

location: {
   country: null,
   state: null,
   city: null
}

location 永远不能为空,只有它的属性可以。

我应该如何进行这些验证?

您必须使用 mixed.default(value)location 的默认值设置为 null,如下所示:

location: yup
    .object()
    .default(null)
    .nullable()
    .shape({
      country: yup.string().required(),
      state: yup.string().required(),
      city: yup.string().required()
    })

更新:

location can never be null, only its properties can be.

你可以这样做:

location: object()
    .shape({
      country: string().default(null).nullable().test(
        value => value === null || value,
      ),
      state: string().default(null).nullable().test(
        value => value === null || value,
      ),
      city: string().default(null).nullable().test(
        value => value === null || value,
      )
    })