是的,验证需要两个字段之一(其中一个是数字数组)

Rub*_*uby 4 validation typescript reactjs yup formik

我正在将 Formik 与 Yup 和 Typescript 一起使用,并将其作为表单的初始值...

const initialValues = {
    title: "",
    overview: "",
    related_items_id: [],
    short_desc: ""
};
Run Code Online (Sandbox Code Playgroud)

这是我的架构......

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.")
});
Run Code Online (Sandbox Code Playgroud)

现在,我需要related_items_id数组或需要的数组short_desc,如果其中一个填充了数据,另一个则不需要,并且使用 Versa,我如何使用类似whenyup 的方法来实现?

这是我创建的一个代码和框,用于显示我在尝试使用 Yup 的when方法时遇到的错误...

https://codesandbox.io/s/formik-yup-required-one-or-the-other-nextjs-gujqv

Art*_* M. 14

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

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!!!!!!!!
Run Code Online (Sandbox Code Playgroud)

  • 您的数组 `['fieldOneName', 'fieldTwoName']` 应该包装在另一个数组中。这可能是由于更新造成的,我不确定。请参阅文档:https://github.com/jquense/yup#objectshapefields-object-nosortedges-arraystring-string-schema 另外,您可以添加该参数的解释吗?谢谢你! (4认同)

Chr*_*erJ 14

如果使用when不是严格要求,我发现使用测试函数更容易做到这一点,因为它更简洁,更容易遵循,并且不需要重复的代码或消息

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')
    );
Run Code Online (Sandbox Code Playgroud)

  • 如何返回错误信息? (2认同)

小智 8

<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'])                                                                              
}                                                                                                        



            
Run Code Online (Sandbox Code Playgroud)

  • 啊,我瞎了,忘记使用 .shape({...}, [['field', 'field2']]) 对不起,现在就买眼镜。 (2认同)

ioe*_*per 6

您可以通过创建于interdepedent一种实现这一目标 related_items_id,并short_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;
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它

const initialValues: InitialValueType = {
    title: "",
    overview: "",
    related_items_id: [],
    // short_desc: "" no longer required
};
Run Code Online (Sandbox Code Playgroud)

要有条件地设置您的 formSchema,请查看文档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"]]
  );
Run Code Online (Sandbox Code Playgroud)