reactjs 是的,验证两个字段中的任何一个是必需的(其中一个是数字数组)

xam8gpfp  于 2023-02-08  发布在  React
关注(0)|答案(4)|浏览(137)

我用的是Formik,Yup和Typescript,我用这个作为表单的初始值...

const initialValues = {
    title: "",
    overview: "",
    related_items_id: [],
    short_desc: ""
};

这是我的计划...

const formSchema = Yup.object().shape({
    title: Yup.string()
        .trim()
        .required("This field is required."),
    overview: Yup.string().required("This field is required."),
    related_items_id: Yup.array()
        .min(1, "Pick at least 1 item")
        .of(Yup.number().required("This field is required.")),
    short_desc: Yup.string().required("This field is required.")
});

现在,我需要related_items_id数组或short_desc,如果一个数组填充了数据,另一个数组就不需要了,反之亦然,我如何使用when之类的东西来完成呢?
下面是我创建的一个codesandbox,它显示了我在尝试使用Yup的when方法时遇到的错误...
https://codesandbox.io/s/formik-yup-required-one-or-the-other-nextjs-gujqv

iyfjxgzm

iyfjxgzm1#

可以通过创建一个在related_items_idshort_desc上相互依赖的类型来实现这一点

export interface BaseType {
    title: string;
    overview: string;
}

interface RelatedItemsType extends BaseType {
  related_items_id?: Array<any>;
  short_desc?: never;
}

interface ShortDescType extends BaseType {
  related_items_id?: never;
  short_desc?: string;
}

export type InitialValueType = RelatedItemsType | ShortDescType;

你可以这样利用它

const initialValues: InitialValueType = {
    title: "",
    overview: "",
    related_items_id: [],
    // short_desc: "" no longer required
};

要有条件地设置formSchema,请 checkout 文档Conditionally Set Required Field(Yup)。

const basicFormSchema = Yup.object().shape(
    {
      title: Yup.string()
        .trim()
        .required("This field is required."),
      overview: Yup.string().required("This field is required."),
      related_items_id: Yup.array().when("short_desc", {
        is: "",
        then: Yup.array()
          .min(1, "Pick at least 1 item")
          .of(Yup.number().required("This field is required.")),
        otherwise: Yup.array()
      }),
      short_desc: Yup.string().when("related_items_id", {
        is: relatedItemsId => relatedItemsId.length === 0,
        then: Yup.string().required("This field is required."),
        otherwise: Yup.string()
      })
    },
    [["related_items_id", "short_desc"]]
  );
wdebmtf2

wdebmtf22#

这是您检查是否至少完成了其中一项的方法。

const schema = yup.object().shape({
  'fieldOneName': Yup.string()
  .when('fieldTwoName', {
    is: (fieldTwo) => !fieldTwo || fieldTwo.length === 0,
    then: Yup.string()
      .required('At least one of the fields is required'),
  }),
  'fieldTwoName': Yup.string()
  .when(codiceFiscale.name, {
    is: (fieldOne) => !fieldOne || fieldOne.length === 0,
    then: Yup.string().
      .required('At least one of the fields is required'),,
  })
}, ['fieldOneName', 'fieldTwoName']) // <-- HERE!!!!!!!!
aor9mmx1

aor9mmx13#

<Formik
            initialValues={{
                email: '',
                mobile: '',
                submit: null,
            }}

            validationSchema = {                                                                                         
    Yup.object().shape({                                                                                 
            'email': Yup.string()                                                                        
                        .when('mobile', {                                                    
                        is: (mobile) => !mobile || mobile.length === 0,                      
                        then: Yup.string()                                                   
                        .required('At least one of the fields is required'),                 
                                    }),                                                                  
            'mobile': Yup.string()                                                                       
                        .when('email', {                                                     
                        is: (email) => !email || email.length === 0,                         
                        then: Yup.string()
                        .required('At least one of the fields is required')
                        })                                                                   
    }, ['email', 'mobile'])                                                                              
}
kknvjkwl

kknvjkwl4#

如果使用when不是一个严格的要求,我发现使用test函数会更容易一些,因为它更简洁、更容易理解,并且不需要重复代码或消息

const has = require('lodash.has'); // lodash's submodule

validationSchema = {                                                                                         
    Yup.object().shape({                                                                                 
            'email': Yup.string(),                                                                  
            'mobile': Yup.string(),
    })
    .test(
        'email or mobile',
        'email or mobile is required',
        (value) => has(value, 'email') || has(value, 'mobile')
    );

相关问题