首页
/ ant-design Form 中 warningOnly 规则详解:让校验警告不阻塞表单提交

ant-design Form 中 warningOnly 规则详解:让校验警告不阻塞表单提交

2026-09-07 14:31:52作者:翟江哲Frasier

本篇基于 warning-only 示例Form 官方文档 的 Rule 配置说明,讲解 ant-design Form 组件中 warningOnly 规则属性的用途与用法:如何为字段配置“仅警告”级别的校验,使其展示警告提示却不触发 onFinishFailed、不阻止提交;并结合 Form.Item 源码测试用例,说明警告与错误在校验流程、必填星号、反馈图标和 useStatus 中的完整差异,适合需要在“强制校验 + 软性提示”之间做区分的表单场景。

一、warningOnly 解决的问题

默认情况下,Form.Itemrules 校验一旦失败,字段状态变为 errorform.submit() 会 reject 并触发 onFinishFailed,表单无法提交。但实际业务中并非所有校验都是“硬约束”,例如:

  • URL 格式不规范但仍允许提交(后台会兜底纠正);
  • 昵称长度偏短,只提示不阻断;
  • 密码强度不够,给出警告但放行。

这类需求在 ant-design 中的做法就是在某条规则上添加 warningOnly: true官方文档 Rule 表格 对其定义如下:

名称 说明 类型 版本
warningOnly 仅警告,不阻塞表单提交 boolean 4.17.0

也就是说,warningOnlyRule 配置项的一个属性(自 4.17.0 起支持),作用是把该条规则校验失败产生的结果从 errors 降级为 warnings:UI 上依然展示提示文案,但提交流程不受影响。

二、完整示例:URL 字段只警告不阻断

仓库中的 warning-only 示例 展示了典型用法:一个 URL 字段同时挂了三条规则,中间一条格式校验标记为 warningOnly

import React from 'react';
import { Button, Form, Input, message, Space } from 'antd';

const App: React.FC = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const [form] = Form.useForm();

  const onFinish = () => {
    messageApi.success('Submit success!');
  };

  const onFinishFailed = () => {
    messageApi.error('Submit failed!');
  };

  const onFill = () => {
    form.setFieldsValue({
      url: 'https://taobao.com/',
    });
  };

  return (
    <>
      {contextHolder}
      <Form
        form={form}
        layout="vertical"
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
        autoComplete="off"
      >
        <Form.Item
          name="url"
          label="URL"
          rules={[
            { required: true },              // 必填失败则阻塞提交
            { type: 'url', warningOnly: true }, // URL 格式仅警告不阻塞
            { type: 'string', min: 6 },         // 长度失败则阻塞提交
          ]}
        >
          <Input placeholder="input placeholder" />
        </Form.Item>
        <Form.Item>
          <Space>
            <Button type="primary" htmlType="submit">Submit</Button>
            <Button htmlType="button" onClick={onFill}>Fill</Button>
          </Space>
        </Form.Item>
      </Form>
    </>
  );
};

export default App;

示例说明(对应 示例说明文档 中的描述):rule 添加 warningOnly 后校验不再阻塞表单提交。具体行为是:

  1. 输入框留空时,required: true 校验失败 → 字段报错,onFinishFailed 被调用;
  2. 输入了非 URL 字符串(长度 ≥ 6)时,type: 'url' 校验失败,但由于带 warningOnly,字段仅显示警告态,点击 Submit 后 onFinish 依然被调用,弹出 “Submit success!”;
  3. 点击 Fill 按钮通过 form.setFieldsValue 填入合法 URL 后,警告消失。

warningOnly 既可以叠加在内置校验(如 type: 'url'minpattern)上,也可以叠加在 required 上;文档同时说明 Rule 支持 object 或 function 两种形式(type Rule = RuleConfig | ((form: FormInstance) => RuleConfig)),函数形式返回的 RuleConfig 中同样可以带 warningOnly

三、源码视角:warningOnly 到底改变了什么

1. 校验结果进入 warnings 而非 errors

Form.Item 内部为每个字段维护 meta(见 genEmptyMeta),其中明确区分了两个数组:

function genEmptyMeta(): Meta {
  return {
    errors: [],
    warnings: [],
    touched: false,
    validating: false,
    name: [],
    validated: false,
  };
}

warningOnly 的规则校验失败后,错误文案被 rc-field-form 底层归类到 meta.warningsForm.Item 源码 随后将自身的 meta.errors/meta.warnings 与所有 noStyle 子字段的结果合并为 mergedErrorsmergedWarnings,分别传给 ItemHolder 渲染帮助文案、aria-describedby 等。因此警告文案依然会展示在字段下方,只是不携带 has-error 的错误态。

2. warningOnly 的 required 不计入必填星号

Form.Item 渲染逻辑 中,isRequired 的推导会显式排除带 warningOnly 的规则:

const isRequired =
  required !== undefined
    ? required
    : rules?.some((rule) => {
        if (
          isPlainObject(rule) &&
          (rule as RuleObject).required &&
          !(rule as RuleObject).warningOnly
        ) {
          return true;
        }
        if (isFunction(rule)) {
          const ruleEntity = rule(context);
          return ruleEntity?.required && !ruleEntity?.warningOnly;
        }
        return false;
      });

这带来两个直接效果:

  • 只有 { required: true, warningOnly: true } 的字段,label 前不会出现必填星号(因为星号由 isRequired 驱动);
  • isRequired 还会用于设置 aria-required源码 L392-L394),因此无障碍属性与星号表现保持一致。

3. 警告态样式类

字段出现 warnings 时,Form.Item 根节点会带上 ant-form-item-has-warning 类名,区别于错误态的 ant-form-item-has-error测试用例 对此有直接断言:

it('warningOnly validate', async () => {
  const { container } = render(
    <Form>
      <Form.Item>
        <Form.Item
          name="test"
          label="test"
          initialValue="bamboo"
          rules={[{ required: true, warningOnly: true }]}
        >
          <Input />
        </Form.Item>
      </Form.Item>
    </Form>,
  );

  await changeValue(0, 'test');
  await changeValue(0, '');

  expect(container.querySelector('.ant-form-item-with-help')).toBeTruthy();
  expect(container.querySelector('.ant-form-item-has-warning')).toBeTruthy();
});

即清空 initialValue 后,字段展示了帮助信息且处于 warning 状态,而提交本身不会被这条 required 规则拦截。

四、与反馈机制的配合

1. hasFeedback 下的警告图标

Form.ItemhasFeedback 会根据校验状态自动派生 success / validating / warning / error 四类图标状态。测试 覆盖了这一组合:

<Form.Item name="warning" hasFeedback rules={[{ required: true, warningOnly: true }]}>
  <Input />
</Form.Item>
...
expect(container.querySelector('.ant-form-item-has-warning')).toBeTruthy();
expect(container.querySelector('.ant-form-item-has-error')).toBeTruthy();

可以看到 warning 字段与 error 字段同时存在时,两者分别落在 has-warning / has-error 状态上,互不影响。

2. 用 useStatus 读取警告文案

自定义子组件可以通过 Form.Item.useStatus() 拿到当前字段的 errorswarnings测试 演示了 warningOnly 消息进入 warnings 通道:

const WarningItem: React.FC = () => {
  const { warnings } = useStatus();
  return <div className="test-warning">{warnings[0]}</div>;
};

<Form.Item
  name="warning"
  rules={[{ required: true, message: 'This is a warning message.', warningOnly: true }]}
>
  <WarningItem />
</Form.Item>

点击提交后,warnings[0] 即渲染出该条警告文案。文档中的 FieldData 表格 也把 warnings(string[] 类型的警告信息)与 errors 并列为字段元信息的一部分,配合 form.getFieldErrorform.getFieldsFormat 等 API 可以编程化地读取警告结果。

五、使用建议与边界

结合示例与源码可以总结几条实践要点:

  1. 粒度是“规则级”而非“字段级”warningOnly 写在某一条 rule 上,同一字段的其他规则失败仍会阻塞提交。示例中 min: 6 不带 warningOnly,短于 6 个字符的输入照样会触发 onFinishFailed
  2. warningOnly + required 不产生星号:从 isRequired 推导逻辑 看,只有非 warningOnly 的 required 规则才标记必填;若需要“提示必填但实际放行”,应只保留 warningOnly 规则,不额外传 required prop。
  3. 版本前提warningOnly 自 4.17.0 起支持,使用旧版本 antd 时需先确认版本(可在项目 package.json 中核对 antd 依赖)。
  4. 警告不是“静默”:warning 文案会出现在字段 help 区域并触发 ant-form-item-with-help/ant-form-item-has-warning 样式,配合 hasFeedback 还有独立图标;它只是不阻断提交,并非不展示。

如果你需要在提交成功后再根据 warnings 做二次确认(例如弹框提示用户 URL 格式可疑),可以在 onFinish 中通过 form 实例读取各字段状态后再决定是否继续请求——warningOnly 让“提示”与“拦截”这两种校验意图在同一个 rules 数组里清晰分离,这正是 warning-only 示例 要演示的核心价值。

登录后查看全文
热门项目推荐
相关项目推荐