[Form] Support per-rule validation debounce without delaying synchronous rules
What problem does this feature solve?
Form.Item currently supports validateDebounce, but the delay is applied to the whole field validation before any rule is evaluated. As a result, synchronous rules are delayed together with asynchronous rules.
A common example is an entity code that must:
- be required, which should be validated immediately;
- be unique, which requires an API request and should be debounced.
Minimal reproduction: StackBlitz
The reproduction uses antd ^6.5.2 and a 1000ms validateDebounce.
Steps:
- Type a non-empty value in the Entity code input.
- Clear the input.
- Observe when the required error is displayed.
Actual behavior:
- The asynchronous uniqueness validator is debounced as intended.
- The
requirederror is also delayed by1000ms. - Adding
validateFirstdoes not make the required validation immediate, because the field-level debounce happens before rule evaluation starts.
Expected behavior:
- The
requiredrule should fail immediately. - The asynchronous uniqueness rule should run only after its debounce interval.
- A new value should cancel or supersede a pending asynchronous validation.
Implementing the debounce inside a custom validator is possible, but every consumer then has to manage timers, stale promises, and race conditions manually. Moving the asynchronous check outside the Form validation system also loses the standard validation lifecycle and feedback.
This use case was already discussed in:
- #44585, where a rule-level API was originally proposed;
- the maintainer comment about
validateFirst; - the implementation PR discussion, which raised the same “immediate required rule debounced custom validator” scenario.
What does the proposed API look like?
Allow validateDebounce to be configured on an individual rule:
<Form.Item
label="Entity code"
name="code"
validateFirst
rules={[
{
required: true,
message: 'Code is required',
},
{
validateDebounce: 1000,
validator: async (_, value) => {
if (!value) {
return;
}
const isUnique = await checkCodeUniqueness(value);
if (!isUnique) {
throw new Error('Code already exists');
}
},
},
]}
>
<Input />
</Form.Item>
Suggested behavior:
- A rule without
validateDebouncestarts immediately. - A rule with
validateDebouncestarts after the configured delay. - Pending validation for that rule is superseded when the field value changes.
- With
validateFirst, rule order is preserved and the delay is applied only when validation reaches the debounced rule. In the example above, an empty value therefore fails immediately and the uniqueness request is not scheduled. - Without
validateFirst, non-debounced rules start immediately while debounced rules wait for their own delay; the field remains validating until all applicable rules settle. - Explicit validation through submit or
validateFieldsshould keep the current behavior and not be delayed.
The existing Form.Item.validateDebounce API should remain backward compatible. If both item-level and rule-level values are provided, a rule-level value could take precedence for that rule, with 0 allowing a rule to opt out of the item-level delay.
The exact precedence can be adjusted if another design better fits the Form validation model. The main requirement is the ability to debounce an expensive asynchronous rule without delaying fast synchronous rules on the same field.
Source: ant-design/ant-design