Antd Form校验没有效果的问题

时间:2025-01-17 16:44:08

问题是这样的:

环境:

antd@

现象:

在这里插入图片描述
如上页面

  1. 出现页面后直接点击按钮触发校验,不会有校验提示,页面没有任何反应
  2. 假如只有其中任何一个,校验正常 比如,没有“模型编码”,只有“模型名称”
  3. 假如先手动在一个框里输入,之后正常 比如,先在“模型名称”里面输入一个值,之后再点按钮

背景:

“模型名称”和“模型编码”都是antd@ - Form,使用Form的validator进行校验

界面代码大致如下

<Form.Item label="模型名称">
          {getFieldDecorator('name', {
            rules: [
              { validator: checkModelCode },
            ],
          })(<Input />)}
        </Form.Item>
<Form.Item label="模型编码">
          {getFieldDecorator('key', {
            rules: [
              { validator: checkModelCode },
            ],
          })(<Input />)}
        </Form.Item>

调用的方法,代码大致如下:

checkModelCode: [
      function*({ delayTimeout, callback }, { call }) {
        if (delayTimeout) {
          yield call(delay, delayTimeout);
        }
        try {
          const { res } = yield call(checkModelCode);
          if(callback){
            callback(res);
          }
        } catch (err) {
          if(callback){
            callback();
          }
        }
      },
      { type: 'takeLatest' },
    ]

原因:

上面的checkModelCode方法中,callback是form的validator方法的参数,作为参数传给了checkModelCode方法
不论校验是否通过,callback方法都是要执行的。否则就无法出现预期的校验效果

而校验方法checkModelCode是takeLatest类型,也即只响应最新的请求。所以,
当我们点击按钮触发校验时,“模型编码”和“模型名称”都会调用checkModelCode,此时只有后一个请求会被响应,也即前一个请求被取消掉,那对应的callback方法也无法被执行到,因此页面没有校验效果
类似于官网:
在这里插入图片描述
之所以在一个框里输入值之后,一切正常,大概是因为输入值已经触发了对这个框的校验。因此,之后点击按钮对整个表单进行校验的时候,antd不会再校验这个表单。

解决办法:

不想去掉takeLatest的话,可以给两个表单分别定义校验的方法,如下:

validateModelName: [
      function*({ callback, delayTimeout }, { call }) {
        if (delayTimeout) {
          yield call(delay, delayTimeout);
        }
      },
      { type: 'takeLatest' },
    ],
    validateModelKey: [
      function*({ callback, delayTimeout }, { call }) {
        if (delayTimeout) {
          yield call(delay, delayTimeout);
        }
      },
      { type: 'takeLatest' },
    ],

其实按照逻辑也应该是这样,自身表单防止连点,不能俩表单的请求混着一起处理呀