我正在使用 Formik 的 FieldArray
将对象动态添加到数组,将其他表单元素渲染为对象 push()
编入数组。
我的架构如下所示:
const EMAIL_SCHEMA = Yup.object().shape({
address: Yup.string().email().required( 'E-mail address is required.' ),
isPreferredContact: Yup.boolean()
})
const SCHEMA = Yup.object().shape({
emails: Yup.array()
.of( EMAIL_SCHEMA )
.ensure()
.compact( v => !v.address )
.required( 'At least one e-mail address is required.' )
})
对于每个电子邮件输入,都有一个相应的复选框来指示它是否是首选的联系电子邮件地址。不需要将电子邮件地址标记为首选。我想做的是验证数组是否包含 最多一个 对象在哪里
isPreferredContact
是 true
.如果数组中有 3 个电子邮件对象且 isPreferredContact
是 false
对他们所有人来说,这是一个有效的状态。也就是说:let values = [
{address: '1@email.com', isPreferredContact: false},
{address: '2@email.com', isPreferredContact: false},
{address: '3@email.com', isPreferredContact: false}
] // OK
let values = [
{address: '1@email.com', isPreferredContact: true},
{address: '2@email.com', isPreferredContact: false},
{address: '3@email.com', isPreferredContact: false}
] // OK
let values = [
{address: '1@email.com', isPreferredContact: true},
{address: '2@email.com', isPreferredContact: true},
{address: '3@email.com', isPreferredContact: false}
] // Invalid
我看到这个答案Yup: deep validation in array of objects
显示
compact()
方法可用于验证 至少一个 ,因为如果从数组中删除“假”值后,数组为空,那么很容易将架构键视为无效。但是,我看不到任何用于验证数组是否包含 的内容。最多 一个具有属性 = 值谓词的对象。
有没有办法做到这一点?
最佳答案
在 GitHub 中查看 Yup 的问题后,盯着 API 文档(addMethod
的文档真的很糟糕),并在 Code Sandbox 中进行测试,我发现这有效:
Yup.addMethod(Yup.array, 'atMostOne', function(args) {
const { message, predicate } = args
return this.test('atMostOne', message, function(list) {
// If there are 2+ elements after filtering, we know atMostOne must be false.
return list.filter(predicate).length < 2
})
})
显然,谓词是一个函数,它接受数组的一个元素并对其执行测试,返回 boolean
.对于标量值数组,这就像
el => el === value
一样简单.对于一组对象,它将是 el => el.property === value
或 el[property] === value
.希望这可以帮助其他对此感到好奇的人。
关于reactjs - 是的,验证对象数组最多包含一个对象,其中属性 = 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62564049/