(是的)如何使用单个 .test() 函数创建多个错误

(Yup) how to create multiple errors using a single .test() function

编辑:虽然公认的解决方案有效,但 this 在我的用例中效果更好

我有一个函数可以验证 输入字段 A 输入字段 B 是否为空 并且按照我构建表单的方式,我只需要编写一个函数来检查两者。 (实际函数要复杂得多,所以我选择创建下面的示例函数)

这是我的测试函数:

function isValid(message) {
    //I don't use the message variable but I added it anyway
    return this.test("isValid", message, function (value) {
    if(!value.A) {
        return createError({path: `${this.path}.A`, message:"A is empty"});
    }
    if(!value.B) {
        return createError({path: `${this.path}.B`, message:"B is empty"});
    }
    return true;
    })

结果是 当 A 和 B 为空时,我 return 第一个 createError 所以函数的其余部分被跳过 这就是 formik.errors 对象看起来像:

{
    parent: {
        A: "A is empty"
    }
}

如何创建错误数组并 return 代替它?

我试过了:

return创建一个 createErrors() 数组,但我得到了相同的结果,

将 createErrors 与一组路径和消息一起使用,但 formik.errors 看起来像这样:

{
    parent.A: { parent.B: "2 errors occured" }
}

而不是 所需的:

{
    parent: {
        a: "A is empty",
        b: "B is empty"
    }
}

您可以使用 Yup 中的 ValidationError 来实现这个目标。 ValidationError accepts array of other ValidationError instances. The individual ValidationError instances are capable of holding path and error message and the parent instance will combine them.

的构造函数

下面是示例测试函数:

import { ValidationError } from 'yup'

const testFunc = (value) => {
    const keys = ['A', 'B']

    const errors = keys.map((key) => {
        if (value[key]) { return null } // Successful validation, no error

        return new ValidationError(
          `${key} is empty`,
          value[key],
          key
        )
    }).filter(Boolean)

    if (errors.length === 0) { return true }

    return new ValidationError(errors)
}

根据the source code判断,createError也可以做同样的事情。

您可以将函数而不是字符串传递给 createError 调用的 message 属性。在这种情况下,该函数将在 createError => ValidationError.formatError here 内调用。如果此函数返回正确构建的 VaildationError 个实例的数组,我们将得到相同的结果。

这是该方法的示例测试函数:

import { ValidationError } from 'yup'

const testFunc = (value, { createError }) => {
    const keys = ['A', 'B']

    const errors = keys.map((key) => {
        if (value[key]) { return null } // Successful validation, no error

        return new ValidationError(
          `${key} is empty`,
          value[key],
          key
        )
    }).filter(Boolean)

    if (errors.length === 0) { return true }

    return createError({
      message: () => errors
    })
}