检查下拉列表的值不在另一个下拉列表中。使用 YUP 的自定义验证

Checking value of drop down is not in another drop down. Custom Validation using YUP

我在 React Formik 表单中有 3 个下拉菜单,每个都有相同的选项集。我想使用 YUP 提供一些自定义验证,以确保每个下拉菜单都选择了唯一值。

在每个字段上设置的 Formik 值采用 {id: somevalue, text: someText }

的形式

我试过如下设置我的验证对象:

const { values } = useFormikContext();

const validation = Yup.object({
    picker1: Yup.object()
        .test('test-name', 'Value must be Unique',
            function (value) {
                 return !((values["picker2"] && values["picker2"].id === value.id) ||
                (values["picker3"] && values["picker3"].id === value.id));
            }),
        ... repeat for other pickers
})

我遇到的问题是,当测试函数执行时,选择器的 formik 值始终为 null,可能是因为 values 的值在创建函数时被限制在范围内。有没有更好的方法来尝试这个,因为 YUP 中关于自定义验证的文档似乎有点稀疏。

所以我想出了如何在不使用 Formik 上下文的情况下做到这一点,而是在其测试方法中使用 Yup 对象。

const validation = Yup.object(){
    picker1: Yup.object()
        .shape({
            id: Yup.string().required(),
            text: Yup.string().required()
        })
        .nullable()
        .test(
            'unique-values',
            'Selected picker values must all be different',
            (data, { parent }) => {
                return (
                    data
                    && (parent.picker2 == null || (parent.picker2 != null && data.id !== parent.picker2.id))
                    && (parent.picker3 == null || (parent.picker3 != null && data.id !== parent.picker3.id))
                )
            }
        ),
    picker2: Yup.object()
        .shape({
            id: Yup.string().required(),
            text: Yup.string().required()
        })
        .nullable()
        .test(
            'unique-values',
            'Selected picker values must all be different',
            (data, { parent }) => {
                return (
                    data
                    && (parent.picker1 == null || (parent.picker1 != null && data.id !== parent.picker1.id))
                    && (parent.picker3 == null || (parent.picker3 != null && data.id !== parent.picker3.id))
                
            }
        ),
    picker3: Yup.object()
        .shape({
            id: Yup.string().required(),
            text: Yup.string().required()
        })
        .nullable()
        .test(
            'unique-values',
            'Selected picker values must all be different',
            (data, { parent }) => {
                return (
                    data
                    && (parent.picker1 == null || (parent.picker1 != null && data.id !== parent.picker1.value))
                    && (parent.picker2 == null || (parent.picker2 != null && data.id !== parent.picker2.id))
                )
            }
        )
};

显然那里有很多重复的代码,而且不是最优雅的。会对任何其他解决方案非常感兴趣。