简体   繁体   English

获取另一个字段的值以在 Yup Schema 中进行验证

[英]Get the value of another field for validation in Yup Schema

I am using Formik with Yup for validation and TypeScript我将 Formik 与 Yup 一起用于验证和 TypeScript

I have a field that needs to validate based on the value of another field.我有一个字段需要根据另一个字段的值进行验证。

The first field is called price and the second field is called tips.第一个字段称为价格,第二个字段称为提示。 The max tip value is 10% of the what ever the price entered is.最高小费值为输入价格的 10%。

I tried to create validation for this using the following:我尝试使用以下方法为此创建验证:

   tips: yup.number()
    .min(0, `Minimum tip is $0`)
    .max( parseFloat(yup.ref('price'))* 0.1, "Maximum tip is 10% of the price.");

however this doesn't compile because yup.ref returns a Ref.但是这不会编译,因为 yup.ref 返回一个 Ref。 How can I get the value of the price field in this validation?如何获取此验证中价格字段的值?

number.max cannot reference other field and calculate with it at validation. number.max无法引用其他字段并在验证时使用它进行计算。

If you want to do this, you need to implement own schema with mixed.test .如果你想这样做,你需要用mixed.test实现自己的模式。
Here is a example.这是一个例子。

  tips: number()
    .min(0, `Minimum tip is $0`)
    .test({
      name: 'max',
      exclusive: false,
      params: { },
      message: '${path} must be less than 10% of the price',
      test: function (value) {
          // You can access the price field with `this.parent`.
          return value <= parseFloat(this.parent.price * 0.1)
      },
    }),

Here is doc .这是 文档
You can check and try how it works here .您可以在这里查看并尝试它的工作原理。

I hope this will help you.我希望这能帮到您。

if you don't want to use this.parent to access the other properties values you can use the context .如果您不想使用this.parent访问其他属性值,则可以使用context

tips: number()
.min(0, `Minimum tip is $0`)
.test(
  'max',
  '${path} must be less than 10% of the price',
  (value, context) => value <= parseFloat(context.parent.price * 0.1),
),

// OR

tips: number()
.min(0, `Minimum tip is $0`)
.test({
      name: 'max',
      exclusive: false,
      params: { },
      message: '${path} must be less than 10% of the price',
      test: (value, context) => value <= parseFloat(context.parent.price * 0.1),
    }),

For referencing other field value we can use this.parent or ctx.parent in case if our value is not nested.为了引用其他字段值,我们可以使用 this.parent 或 ctx.parent 以防我们的值未嵌套。

object({
   title: string(),
   price: string().test('test-name', 'test-message', (value, ctx) => {
       let title = ctx.parent.title;
   }),
   foo: string()
       .test('test-name1', 'test-message1', function (value) {
           let title = this.parent.title
       })
})

but if we have nested value parent is going to give parent of nested value.但是如果我们有嵌套值,父级将给出嵌套值的父级。 in this case parent is not going to work if we want to access very parent value.在这种情况下,如果我们想访问非常父的值,父将不会工作。 we can access parent value with ctx.from.我们可以使用 ctx.from 访问父值。 ctx.from contains parents from bottom to top. ctx.from 从下到上包含父母。 for example:例如:

object({
    title: string(),
    ourObject: object({
        param1: string(),
        param2: string()
            .test('test-name', 'test-msg', (value, ctx) => {
                let title = ctx.from[ctx.from.length - 1].value.title
            })
    })
})

or we can easily access any data we want with providing context to schema when validating或者我们可以通过在验证时为模式提供上下文来轻松访问我们想要的任何数据

object({
    price: string(),
    foo: string()
        .test('test-name', 'test-message', (value, ctx) => {
            let arr = ctx.context.arr;
        })
})
    .validate({ price: 5, foo: 'boo' }, { context: { arr: [1, 2] } })
    .then(() => ...)
    .catch((err) => ...)

doc 文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM