antd 4.x中在Form rule的validator使用validateFields无法正常返回

7,294 阅读1分钟

Bug场景:

在一个表单中,有手机号和验证码两项,在输入验证码后做异步校验,需要在前端先验证手机号是否合法。

代码如下:

<Form.Item label="手机号" name="sms_mobile" rules={[
    { required: true, message: '请填写手机号码'},
    { pattern: /^1(3|4|5|7|8|6|9)\d{9}$/, message: '请输入11位电话号码' },
]}>
    <Input />
</Form.Item>
<Form.Item label="验证码" name="sms_vcode" rules={[{ required: true, validator: validCode }]}>
    <Input />
</Form.Item>

验证码的validator方法如下:

 const validCode = (rule, value) => {
    return new Promise((resolve, reject) => {
      validateFields(['sms_mobile']).then(values => {
        //这里应该是验证手机号合法才执行then
        //再执行异步校验
      }).catch(err => {
        //这里应该是验证手机号失败才执行catch
      })
    }
  };

但在输入验证码,做validCode校验时,即使手机号合法,也都跳到了catch里,但显示的err里是空的,不确定这算不算是antd 4的bug。解决方法做了一个转折,为了保险,还是把校验结果,放到了finally里去判断。

解决方法:

const validCode = (rule, value) => {
    return new Promise((resolve, reject) => {
      let mobileError = false;
      validateFields(['sms_mobile']).then(values => {
        mobileError = false;
      }).catch(err => {
        if(err.errorFields.length > 0) {
          mobileError = true;
        }
      }).finally((res,a) => {
        //如果验证失败,就中断下面的验证
        if(mobileError){
          resolve();
          return;
        }
        const code = getFieldValue('sms_vcode');
        //这里是异步校验内容
        //...
      });
    }
  };

在网上没有看到有人报这样的bug,但在git issue中看到别人的代码在codesandbox中,改成这样,仍然是同样的问题,验证通过,then不执行,直接执行catch 先记录一下,如果有天发现不是bug,再来修改。