Antd Form 表单实现单项自定义请求校验

应用场景

我们经常会结合 Modal 和 Form 来实现一些对话框内提交信息的需求,而有些信息是需要在填写完成后立即校验的,看上去像这样:

在这里插入图片描述

属性准备

要实现这样的功能,需要准备以下属性:

属性说明
validateTrigger字段校验的时机onChange/onBlur/onFocus/…
validator自定义校验函数rules 中的自定义校验,接收 Promise 作为返回值
validateStatus校验状态success/warning/error/validating
hasFeedback展示校验状态图标(建议只配合 Input 组件使用)boolean
help提示信息设置后,会覆盖之前自动生成的提示信息

注意, 使用上述这些属性后,相当于校验的状态、提示信息等完全是受控的,不再接受 form 表单默认的校验功能,需要我们自己手动实现。

代码实现

结构

const [validateStatus, setValidateStatus] = useState(undefined); // 受控的校验状态
const [validateHelp, setValidateHelp] = useState(''); // 校验的提示信息

//(返回 Promise)
const handleIdValidator = () => {
    // ...实现自定义校验方法
}

<Form.Item
    label="ID"
    name="id"
    hasFeedback
    validateTrigger="onBlur" // 输入完成, 失去焦点后开始校验
    validateStatus={validateStatus}
    help={validateHelp}
    rules={[
        { required: true },
        { validator: handleIdValidator },
    ]}
>
    <Input placeholder="请输入ID" />
</Form.Item>

自定义校验方法

接下来我们来实现一个自定义的校验方法:

const handleIdValidator = async (_, value) => {
    setValidateHelp('ID校验中......');

    // step1. 非空校验
    if (value === undefined || !value.trim()) {
        setValidateStatus('error');
        setValidateHelp('请输入产商ID!');
        throw new Error();
    }

    // step2. 开始校验
    setValidateStatus('validating');
    try {
        const res = await api(value); // todo 后端校验请求
        if (res) {
            setValidateStatus('success');
            setValidateHelp(undefined);
            return res;
        }
    } catch (e) {
        setValidateStatus('error');
        setValidateHelp('无效的厂商ID!');
        throw new Error(e); // ↑ 错误信息会显示手动设置的 help(不会显示 Error 中的值)
    }
}
// mock 一个校验请求
const api = (value) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (value % 2) resolve('校验成功');
            reject('无效的ID');
        }, 800);
    });
};

提交优化

在实现功能后,点击确定按钮会发现 form 表单又重新校验了一遍。是这因为大部分情况下,我们的提交按钮设置了htmlType="submit",该属性会在点击时默认提交 form 表单数据,此时 antd 的 form 会自动进行验证,如果校验成功,则会调用 onFinish 配置的回调。而这里,我们的信息都是必填且在填写时已经校验过了,所以按钮可以移除 submit 属性,直接获取 form 表单数据,进行提交。

const submitForm = async () => {
    // 直接获取所有 form 表单数据
    const formData = form.getFieldsValue();
    try {
        await api(formData); // todo 
    } catch (error) {
        console.log('🚀 ~ error', error);
    } finally {
        // 重置
        setValidateStatus(undefined);
        setValidateHelp(undefined);
    }
};

参考资料

<button> type 属性

自定义校验状态

自定义 validator

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值