Yup 模式中的可选字段验证

问题描述 投票:0回答:3

我使用

react-hook-form
yup
进行表单验证,并希望某些字段是可选的(空)。

按照他们的文档,我正在使用

nullable()
optional()
但它仍在验证中:

export const updateAddressSchema = yup.object({
  address: yup
    .string()
    .nullable()
    .optional()
    .min(5, "Address must be more than 5 characters long")
    .max(255, "Address must be less than 255 characters long"),
  city: yup
    .string()
    .nullable()
    .optional()
    .max(32, "City name must be less than 32 characters long"),
  postal_code: yup
    .string()
    .nullable()
    .optional()
    .length(10, "Postal code must be 10 characters long"),
  phone: yup
    .string()
    .nullable()
    .optional()
    .min(10, "Phone number must be more than 10 characters long")
    .max(20, "Phone number must be less than 20 characters long"),
});

有什么正确的方法可以做到这一点吗?

javascript html reactjs validation yup
3个回答
14
投票

您需要使用

.when
进行条件验证,如下所示。我只添加了
address
city
,您可以像这样添加其他。

export const updateAddressSchema = yup.object().shape({

  address: yup.string().when("address", (val, schema) => {
       if(val?.length > 0) {  //if address exist then apply min max else not
          return yup.string().min(5, "min 5").max(255, "max 255").required("Required");
       } else { 
          return yup.string().notRequired();
       }
  }),

  city: yup.string().when("city", (val, schema) => {
       if(val?.length > 0) {
          return yup.string().max(32, "max 32").required("Required");
       }
       else { 
          return yup.string().notRequired();
       }
  }),
  
 }, [
     ["address", "address"], 
     ["city", "city"], 
    ]                   //cyclic dependency
 );

此外,还需要添加循环依赖


4
投票

非常感谢@Usama的回答和解决方案!

我在使用他们的解决方案时遇到了另一个问题。如果提交空值,我的后端 API 会忽略空值并返回之前的值。问题是,在初始渲染时,文本字段的值为空,但在选择并键入然后删除键入的字母以使其再次为空(不提交)之后,其值将更改为空字符串,因此我的 API 会抛出错误并且不会更新用户信息。

我设法修复它的方法是使用

yup
.transform()
方法将类型从空字符串转换为 null(如果文本字段未填充):

export const updateAddressSchema = yup.object().shape(
  {
    address: yup.string().when("address", (value) => {
      if (value) {
        return yup
          .string()
          .min(5, "Address must be more than 5 characters long")
          .max(255, "Address must be less than 255 characters long");
      } else {
        return yup
          .string()
          .transform((value, originalValue) => {
            // Convert empty values to null
            if (!value) {
              return null;
            }
            return originalValue;
          })
          .nullable()
          .optional();
      }
    }),
    ......................
  },
  [
    ["address", "address"],
    ......................,
  ]
);

我真的希望这对某人有帮助。


0
投票
namespace: yup.lazy((value) => {
  if (value !== undefined && value !== "") {
    return yup.string().min(6).max(64).lowercase();
  }
  return yup.string().nullable().optional();
}),

这个方法对我们有用。

© www.soinside.com 2019 - 2024. All rights reserved.