最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Yup conditional validation based on a a non field value - Stack Overflow

programmeradmin1浏览0评论

I am trying to create a yup schema where based on a variables value the schema changes slightly. In my case depending on the value of prop myCondition I need to make a field as required. I would like to know if there is any better way I can achieve the same using Yup. Here's my current code structure that works:

// config.js
const COMMON_SCHEMA = {
  str1: yup
    .string()
    .nullable()
    .required('Please input str1'),
  str3: yup
    .string()
    .nullable()
};
const VALIDATION_SCHEMA_1 = yup.object().shape({
  ...COMMON_SCHEMA,
  str2: yup.string().nullable(),
});

const VALIDATION_SCHEMA_2 = yup.object().shape({
  ...COMMON_SCHEMA,
  str2: yup
    .string()
    .nullable()
    .required('Please input str2'),
});

const SCHEMAS = {
  VALIDATION_SCHEMA_1,
  VALIDATION_SCHEMA_2
}
export default SCHEMAS;

the following is how I conditionally choose different schemas:

// app.js
import SCHEMAS from './config';
...

<Formik
  validationSchema={
    this.props.myCondition === true
      ? SCHEMAS.VALIDATION_SCHEMA_1
      : SCHEMAS.VALIDATION_SCHEMA_2
  }
>
...
</Formik>

I feel like I can achieve whatever I am doing above in an easier way with yup. One of the approaches I tried was to pass in the prop myCondition into config file and work with it's value by using yup.when() but when only works if the value you want to use is also a part of the form so I couldn't achieve the same.

I am trying to create a yup schema where based on a variables value the schema changes slightly. In my case depending on the value of prop myCondition I need to make a field as required. I would like to know if there is any better way I can achieve the same using Yup. Here's my current code structure that works:

// config.js
const COMMON_SCHEMA = {
  str1: yup
    .string()
    .nullable()
    .required('Please input str1'),
  str3: yup
    .string()
    .nullable()
};
const VALIDATION_SCHEMA_1 = yup.object().shape({
  ...COMMON_SCHEMA,
  str2: yup.string().nullable(),
});

const VALIDATION_SCHEMA_2 = yup.object().shape({
  ...COMMON_SCHEMA,
  str2: yup
    .string()
    .nullable()
    .required('Please input str2'),
});

const SCHEMAS = {
  VALIDATION_SCHEMA_1,
  VALIDATION_SCHEMA_2
}
export default SCHEMAS;

the following is how I conditionally choose different schemas:

// app.js
import SCHEMAS from './config';
...

<Formik
  validationSchema={
    this.props.myCondition === true
      ? SCHEMAS.VALIDATION_SCHEMA_1
      : SCHEMAS.VALIDATION_SCHEMA_2
  }
>
...
</Formik>

I feel like I can achieve whatever I am doing above in an easier way with yup. One of the approaches I tried was to pass in the prop myCondition into config file and work with it's value by using yup.when() but when only works if the value you want to use is also a part of the form so I couldn't achieve the same.

Share Improve this question asked Apr 6, 2020 at 16:20 Nagarjun PrasadNagarjun Prasad 9144 gold badges17 silver badges32 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 11

This can be achieved by the following way:

You can wrap your schema in a function and pass your conditional prop:

const wrapperSchema = (condition) => 
  Yup.object().shape({
    ...COMMON_SCHEMA,
    str2: yup.string()
     .when([], {
       is: () => condition === true,
       then: yup.string().nullable(),
       otherwise: yup.string().required('Please input str2'),
     }),
  });

Please note that first param of when is a required param, you can also pass e.g. ["title", "name"] where title and name can be your field values, and you can retrieve and use them in is callback, in the same order, if you have to.

You can conditionally add validation directly in the validationSchema, like this: https://stackoverflow.com/a/56216753/8826314

Edited to add, you can include your value in the initial form, so that you can do the when check against that field. For example:

<Formik 
  initialValues={
    ...,
    str2
  }
  validationSchema={
    ...,
    str2: yup.object().when('str2', {
      is: str2 => condition check that returns boolean,
      then: Yup.string().nullable(),
      otherwise: Yup.string().nullable().required('Please input str2')
    })
}
>
...
</Formik>

I had a similar issue and solved it as an input to my validation schema in the following way (this is a generic example):

export validationSchemaExample = (condition: boolean) =>
  yup.object().shape({
    field: yup.string().when([], {
      is: () => condition,
      then: () => yup.string().required("This field is required")
    }),

And then I refer to it as follows:

    <Formik
      ...
      validationSchema={validationSchemaExample(condition)}
    >
发布评论

评论列表(0)

  1. 暂无评论