背景描述:
做运营系统、后台系统、ToB项目时避免不了需要研发表单,要填写各种内容。
博主有一年左右没做后台了,重新拾起来。
操作:给Form.Item
的属性rules
,给rules
里面指定了 { required: true }, 同时给了 validator
自定义校验方法。
问题描述:自定义校验后,required 必填不起效。
环境:
Ant Design版本:4.24.10, React版本: 17.0.2
代码:
❎ 错误代码:
<Form.Item
name="id"
label="ID"
validateTrigger={['onBlur']}
rules={[
{ required: true, message: '必填' },
{ pattern: /^.{0,15}$/, message: '不超过15个字母或数字' },
{
validator: (rule, value, callback) => {
// 校验重复, xxxApi这里是某异步请求
xxxApi({ id: value })
.then(res => {
return Promise.resolve();
})
.catch(e => {
return Promise.reject(e.message || '货品ID已存在');
});
},
},
]}
// 正则中的.代表\n以外的任意字符
>
<Input
placeholder="请输入,不超过15个字母或数字"
allowClear
/>
</Form.Item>
遇到这个问题,输入框打完字,鼠标离开,就是不出现“必填”的提示。
解决:
排查好一会儿,才发现validator
方法没写 return
!
✅ 正确代码:
{
validator: (rule, value, callback) => {
// 校验重复, xxxApi这里是某异步请求
return xxxApi({ id: value }) // 这里!!! 加 return
.then(res => {
return Promise.resolve();
})
.catch(e => {
return Promise.reject(e.message || '货品ID已存在');
});
},
}
validator也可以这样写(不用箭头函数):
{
validator(rule, value, callback){
// ...
},
}
还有一种原因,validator方法
处理不好的话,会覆盖 require:true
。
代码如下:
<Form.Item
label="ID"
name="id"
validateTrigger={['onBlur']}
rules={[
{ required: true, message: '必填' },
{
validator: handleVerifyExit,
},
]}
>
<Input placeholder="请输入" style={{ width: inputWidth }} allowClear />
</Form.Item>
// 校验函数可以抽出去
function handleVerifyExit(_: any, val: any) {
// 注意这行 !!!是为了避免输入为空时去请求接口,有值才发校验请求
if (!val) return ;
return verifyCrmInfo({
type: form.getFieldValue('type'), // 另一个输入框的值
id: val,
}).then(
res => {
console.log('校验成功:', res);
},
res => {
console.log('校验失败:', val, res);
return Promise.reject(res.message);
},
);
}
注意这里的: if (!val) return ;
它会在输入为空时,将必填的校验覆盖。
理解一下,这里的逻辑是:输入项未填时,为false,那么return。这就代表了返回是空。因此不会提示必填。
✅正确代码:
if (!value || value.trim() === '') {
return Promise.reject('This field is required');
}
这样就解决了必填校验未生效的问题(实际还是需要逻辑严谨)
记录一下,方便回顾,亦分享经验,希望帮助到踩坑的小伙伴~