错误:Yup 验证的循环依赖

Ray*_*Man 7 javascript validation reactjs yup

我有这个 Yup 验证模式,其中包括对 min_amount 和 max_amount 值的检查。我在 ReactJS 表单上使用它。

const amountsSchema = yup.object({
  min_amount: yup.number()
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('min_amount must be a number')
    .when('max_amount', {
      is: '',
      then: yup.number().min(1),
      otherwise: yup.number().lessThan(yup.ref('max_amount'), 'min_amount must be less than maximum amount'),
    })
    .required(),

  max_amount: yup.number()
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('max_amount must be a number')
    .when('min_amount', {
      is: '',
      then: yup.number().min(1),
      otherwise: yup.number().moreThan(yup.ref('min_amount'), 'max_amount must be greater than minimum amount'),
    })
    .required(),
});
Run Code Online (Sandbox Code Playgroud)

问题是它会引发这个错误:

错误:循环依赖,节点为:“max_amount”

如何正确编写架构,以便无论用户首先/最后填写哪个字段,架构都会在用户填写表单时正确比较这两个字段?促使我这样写的原因是之前是这样的:

const amountsSchema = yup.object({
  min_amount: yup.number()
    .min(1)
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('min_amount must be a number')
    .required(),

  max_amount: yup.number()
    .min(1)
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('max_amount must be a number')
    .moreThan(yup.ref('min_amount'), 'max_amount must be greater than minimum amount')
    .required(),
});
Run Code Online (Sandbox Code Playgroud)

用户可以先填写 max_amount,然后填写更大的 min_amount 并绕过验证。

小智 13

我想你可以尝试

const amountsSchema = yup.object().shape({
  min_amount: yup.number()
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('min_amount must be a number')
    .when('max_amount', {
      is: '',
      then: yup.number().min(1),
      otherwise: yup.number().lessThan(yup.ref('max_amount'), 'min_amount must be less than maximum amount'),
    })
    .required(),

  max_amount: yup.number()
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('max_amount must be a number')
    .when('min_amount', {
      is: '',
      then: yup.number().min(1),
      otherwise: yup.number().moreThan(yup.ref('min_amount'), 'max_amount must be greater than minimum amount'),
    })
    .required(),
}, ['max_amount', 'min_amount']);
Run Code Online (Sandbox Code Playgroud)

  • 我认为这没有帮助,因为它没有解释为什么需要使用数组来避免错误。 (8认同)
  • 为了理解字段名称数组,此评论/问题帮助我:https://github.com/jquense/yup/issues/193#issuecomment-437878160。顺便说一句,对于 ts,我必须提供一个元组数组。类似于:`[['max_amount', 'min_amount']]` (3认同)
  • 解释它如何工作以及为什么文档中缺少它的链接 https://github.com/jquense/yup/issues/1339 (2认同)