reactjs Yup + useFormik -基于某些参数的条件必填字段

kcwpcxri  于 2023-02-22  发布在  React
关注(0)|答案(3)|浏览(119)

我有一个验证模式对象:

SCHEMA = object().shape({
  ...
  someField: string().required(validation_keys.required),
  ...
});

我在组件中使用useFormik

const formik = useFormik({
  initialValues: values,
  onSubmit: ...,
  validationSchema: SCHEMA,
});

我一直在寻找一种方法来将参数传递给我的SCHEMA,这样当参数为true时,就需要someField ......我阅读了有关上下文的内容,也尝试使用when(),但这些都不适合我......
我的目标是基于组件属性验证someField,而不是基于formik中的其他字段。

validationSchema={yup.object().shape({
    someField: yup
      .string()
      .when("xxx", {
        is: true,
        then: yup.string().required("Required"),
        otherwise: yup.string(),

      })
  })
}

xxx应该被传递到我的React组件中使用useFormik的验证模式

bogh5gae

bogh5gae1#

你可以做这样的事。

const validationSchema= Yup.object({
      custom_field: Yup.string().test(
        "match",
        "Custom validation enabled",
        function () {
          if (!shouldFormValidate) return true;
          return false;
        }
      )
    });

Here工作代码和框。

uxhixvfz

uxhixvfz2#

如果要基于React组件属性验证字段,可以使用withMutation

schema = object({
  ...,
  someField: string(),
  ...
});

if(validation_keys.required) {
  schema.fields.someField.withMutation(schema => {
    schema.required();
  });
}

示例

ozxc1zmp

ozxc1zmp3#

虽然我不确定您是否可以仅在传递给Formik的模式中实现这一点,但是您可以在Yup Schema.validate中使用options参数。
Schema.validate接受并返回以下内容:Schema.validate(value: any, options?: object): Promise<InferType<Schema>, ValidationError>
其中选项为:

interface Options {
  // when true, parsing is skipped an the input is validated "as-is"
  strict: boolean = false;
  // Throw on the first error or collect and return all
  abortEarly: boolean = true;
  // Remove unspecified keys from objects
  stripUnknown: boolean = false;
  // when `false` validations will be performed shallowly
  recursive: boolean = true;
  // External values that can be provided to validations and conditionals
  context?: object;
}

最后一个键,context将帮助您解决这个问题,您可以使用它来传递值,以便稍后在验证期间访问这些值。
来自文档的示例:

let schema = object({
  isBig: boolean(),
  count: number()
    .when('isBig', {
      is: true, // alternatively: (val) => val == true
      then: (schema) => schema.min(5),
      otherwise: (schema) => schema.min(0),
    })
    .when('$other', ([other], schema) =>
      other === 4 ? schema.max(6) : schema,
    ),
});

await schema.validate(value, { context: { other: 4 } });

这个解决方案显然意味着您必须手动调用schema.validate,并且不能依赖Formik为您做这件事,但是也有方法可以做到这一点,所以如果您 * 真的 * 需要在验证过程中提供额外的参数,您可以从技术上做到这一点。

相关问题