使用 validateFields,点击保存的时候控制台会打印警告,但是表单中无飘红提示。

问题背景

写了一个表单校验,用来验证输入的字符串是否全为空格。当我点击保存的时候(调用 validateFields 方法),在控制台提示了如下警告:

代码是这样的:

<FormItem
    label="规格"
    className="contact-detail-info-form-item"
    {...formItemLayout}
>
    {
        getFieldDecorator('specification', {
            initialValue: data.specification,
            rules: [
                {
                    required: true,
                    message: '请输入规格',
                },
                {
                    validator: (rule, value, callback) => {
                        /* 注意看这里!!! */
                        if (value.length && !value.trim().length) {
                            callback('规格文案不能全为空格');
                        }
                        else {
                            callback();
                        }
                    }
                }
            ],
        })(<Input
            allowClear
            className="custom-input"
            placeholder="请输入规格"
        />)
    }
</FormItem>

解决方案

通过查阅相关问题发现,只要在 validator 方法的判断中加上对于 value 值本身的判断就能解决问题。像下面这样:

<FormItem
    label="规格"
    className="contact-detail-info-form-item"
    {...formItemLayout}
>
    {
        getFieldDecorator('specification', {
            initialValue: data.specification,
            rules: [
                {
                    required: true,
                    message: '请输入规格',
                },
                {
                    validator: (rule, value, callback) => {
                        /* 注意看这里!!!加上了 value 的判断 */
                        if (value && !value.trim().length) {
                            callback('规格文案不能全为空格');
                        }
                        else {
                            callback();
                        }
                    }
                }
            ],
        })(<Input
            allowClear
            className="custom-input"
            placeholder="请输入规格"
        />)
    }
</FormItem>

加上对于 value 的判断后再去校验就出现飘红提示了。

问题原因分析

虽然问题解决了,但是如此怪异的问题我还是得弄清楚原因才行,不然再次遇到同类问题的时候可能不知道该怎么处理。

对比了一下前后的区别,发现将 value.length 改成 value 的区别在于 value.length 这个表达式本身就可能报错。比如当 valueundefined 时。

validator 非常强调的一件事就是 callback 方法必须要被执行。而当 valueundefined 时,程序在运行时就会报错,导致 callback 方法没有被调用。

而程序报错没有却没有在控制台看到错误打印的原因是可能是因为 Antd Form validator 外部使用了 try...catch 对错误进行捕获。

实践出真知。

为了验证这个猜想的正确性,我在代码代码中添加了如下的打印:

// 校验空格
const validateBlank = (rule: any, value: string, callback: (str?: string) => void) => {
    console.log(1);
    if (value.length && !value.trim().length) {
        console.log(2);
        callback('规格文案不能全为空格');
    }
    else {
        console.log(3);
        callback();
    }
};

然后点击保存。发现在控制台中仅仅打印了 1。这样的验证结果是符合我的猜想的。为了更加坚定这个结论,我查阅了 Antd 文档。

知子莫如父。

我在 Antd 文档中发现了这样一个FAQ:自定义 validator 没有效果.

描述如下:

这是由于你的 validator 有错误导致 callback 没有执行到。你可以选择通过 async 返回一个 promise 或者使用 try...catch 进行错误捕获:

这段描述的第一句话就正中下怀啊。官方提供的解决方案是在 validator 方法内部使用 try...catch 进行错误捕获,然后在 catch 语句中调用一下 callback。详情参见上方的文档。

参考链接

  1. 控制台输入框_antdvue:form表单提交时,只在控制台输出error,输入框不标红 底下也没提示....

拓展

  1. antd-Form表单设置validateFields校验无飘红提示.