feat: Form validation support validateDebounce (#44633)

* chore: bump rc-field-form

* docs: add debounce demo

* docs: update demo

* test: update snapshot

* docs: typo
This commit is contained in:
二货爱吃白萝卜 2023-09-05 19:52:06 +08:00 committed by GitHub
parent 69c52b7a5b
commit ee8cf22aa6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 375 additions and 1 deletions

View File

@ -135,6 +135,7 @@ export default function ItemHolder(props: ItemHolderProps) {
'validateTrigger',
'valuePropName',
'wrapperCol',
'validateDebounce',
])}
>
{/* Label */}

View File

@ -27899,6 +27899,168 @@ exports[`renders components/form/demo/validate-static.tsx extend context correct
exports[`renders components/form/demo/validate-static.tsx extend context correctly 2`] = `[]`;
exports[`renders components/form/demo/validate-trigger.tsx extend context correctly 1`] = `
<form
autocomplete="off"
class="ant-form ant-form-vertical"
id="trigger"
style="max-width: 600px;"
>
<div
class="ant-alert ant-alert-info ant-alert-no-icon"
data-show="true"
role="alert"
>
<div
class="ant-alert-content"
>
<div
class="ant-alert-message"
>
Use 'max' rule, continue type chars to see it
</div>
</div>
</div>
<div
class="ant-form-item"
>
<div
class="ant-row ant-form-item-row"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
for="trigger_field_a"
title="Field A"
>
Field A
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<div
class="ant-form-item-control-input-content"
>
<span
class="ant-input-affix-wrapper ant-input-affix-wrapper-has-feedback"
>
<input
class="ant-input"
id="trigger_field_a"
placeholder="Validate required onBlur"
type="text"
value=""
/>
<span
class="ant-input-suffix"
/>
</span>
</div>
</div>
</div>
</div>
</div>
<div
class="ant-form-item"
>
<div
class="ant-row ant-form-item-row"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
for="trigger_field_b"
title="Field B"
>
Field B
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<div
class="ant-form-item-control-input-content"
>
<span
class="ant-input-affix-wrapper ant-input-affix-wrapper-has-feedback"
>
<input
class="ant-input"
id="trigger_field_b"
placeholder="Validate required debounce after 1s"
type="text"
value=""
/>
<span
class="ant-input-suffix"
/>
</span>
</div>
</div>
</div>
</div>
</div>
<div
class="ant-form-item"
>
<div
class="ant-row ant-form-item-row"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
for="trigger_field_c"
title="Field C"
>
Field C
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<div
class="ant-form-item-control-input-content"
>
<span
class="ant-input-affix-wrapper ant-input-affix-wrapper-has-feedback"
>
<input
class="ant-input"
id="trigger_field_c"
placeholder="Validate one by one"
type="text"
value=""
/>
<span
class="ant-input-suffix"
/>
</span>
</div>
</div>
</div>
</div>
</div>
</form>
`;
exports[`renders components/form/demo/validate-trigger.tsx extend context correctly 2`] = `[]`;
exports[`renders components/form/demo/warning-only.tsx extend context correctly 1`] = `
<form
autocomplete="off"

View File

@ -11864,6 +11864,166 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
</form>
`;
exports[`renders components/form/demo/validate-trigger.tsx correctly 1`] = `
<form
autocomplete="off"
class="ant-form ant-form-vertical"
id="trigger"
style="max-width:600px"
>
<div
class="ant-alert ant-alert-info ant-alert-no-icon"
data-show="true"
role="alert"
>
<div
class="ant-alert-content"
>
<div
class="ant-alert-message"
>
Use 'max' rule, continue type chars to see it
</div>
</div>
</div>
<div
class="ant-form-item"
>
<div
class="ant-row ant-form-item-row"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
for="trigger_field_a"
title="Field A"
>
Field A
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<div
class="ant-form-item-control-input-content"
>
<span
class="ant-input-affix-wrapper ant-input-affix-wrapper-has-feedback"
>
<input
class="ant-input"
id="trigger_field_a"
placeholder="Validate required onBlur"
type="text"
value=""
/>
<span
class="ant-input-suffix"
/>
</span>
</div>
</div>
</div>
</div>
</div>
<div
class="ant-form-item"
>
<div
class="ant-row ant-form-item-row"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
for="trigger_field_b"
title="Field B"
>
Field B
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<div
class="ant-form-item-control-input-content"
>
<span
class="ant-input-affix-wrapper ant-input-affix-wrapper-has-feedback"
>
<input
class="ant-input"
id="trigger_field_b"
placeholder="Validate required debounce after 1s"
type="text"
value=""
/>
<span
class="ant-input-suffix"
/>
</span>
</div>
</div>
</div>
</div>
</div>
<div
class="ant-form-item"
>
<div
class="ant-row ant-form-item-row"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
for="trigger_field_c"
title="Field C"
>
Field C
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<div
class="ant-form-item-control-input-content"
>
<span
class="ant-input-affix-wrapper ant-input-affix-wrapper-has-feedback"
>
<input
class="ant-input"
id="trigger_field_c"
placeholder="Validate one by one"
type="text"
value=""
/>
<span
class="ant-input-suffix"
/>
</span>
</div>
</div>
</div>
</div>
</div>
</form>
`;
exports[`renders components/form/demo/warning-only.tsx correctly 1`] = `
<form
autocomplete="off"

View File

@ -0,0 +1,7 @@
## zh-CN
对于有异步校验的场景,过于频繁的校验会导致后端压力。可以通过 `validateTrigger` 改变校验时机,或者 `validateDebounce` 改变校验频率,或者 `validateFirst` 设置校验短路。
## en-US
For the async validation scenario, too frequent verification will cause backend pressure. You can change the verification timing through `validateTrigger`, or change the verification frequency through `validateDebounce`, or set the verification short circuit through `validateFirst`.

View File

@ -0,0 +1,40 @@
import React from 'react';
import { Alert, Form, Input } from 'antd';
const App: React.FC = () => (
<Form name="trigger" style={{ maxWidth: 600 }} layout="vertical" autoComplete="off">
<Alert message="Use 'max' rule, continue type chars to see it" />
<Form.Item
hasFeedback
label="Field A"
name="field_a"
validateTrigger="onBlur"
rules={[{ max: 3 }]}
>
<Input placeholder="Validate required onBlur" />
</Form.Item>
<Form.Item
hasFeedback
label="Field B"
name="field_b"
validateDebounce={1000}
rules={[{ max: 3 }]}
>
<Input placeholder="Validate required debounce after 1s" />
</Form.Item>
<Form.Item
hasFeedback
label="Field C"
name="field_c"
validateFirst
rules={[{ max: 6 }, { max: 3, message: 'Continue input to exceed 6 chars' }]}
>
<Input placeholder="Validate one by one" />
</Form.Item>
</Form>
);
export default App;

View File

@ -26,6 +26,7 @@ High performance Form component with data scope management. Including data colle
<code src="./demo/layout-can-wrap.tsx">label can wrap</code>
<code src="./demo/warning-only.tsx">No block rule</code>
<code src="./demo/useWatch.tsx">Watch Hooks</code>
<code src="./demo/validate-trigger.tsx">Validate Trigger</code>
<code src="./demo/validate-only.tsx">Validate Only</code>
<code src="./demo/form-item-path.tsx">Path Prefix</code>
<code src="./demo/dynamic-form-item.tsx">Dynamic Form Item</code>
@ -142,6 +143,7 @@ Form field component for data bidirectional binding, validation, layout, and so
| shouldUpdate | Custom field update logic. See [below](#shouldupdate) | boolean \| (prevValue, curValue) => boolean | false | |
| tooltip | Config tooltip info | ReactNode \| [TooltipProps & { icon: ReactNode }](/components/tooltip#api) | - | 4.7.0 |
| trigger | When to collect the value of children node. Click [here](#components-form-demo-customized-form-controls) to see an example | string | `onChange` | |
| validateDebounce | Delay milliseconds to start validation | number | - | 5.9.0 |
| validateFirst | Whether stop validate on first rule of error for this field. Will parallel validate when `parallel` configured | boolean \| `parallel` | false | `parallel`: 4.5.0 |
| validateStatus | The validation status. If not provided, it will be generated by validation rule. options: `success` `warning` `error` `validating` | string | - | |
| validateTrigger | When to validate the value of children node | string \| string\[] | `onChange` | |

View File

@ -27,6 +27,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*ylFATY6w-ygAAA
<code src="./demo/layout-can-wrap.tsx">表单标签可换行</code>
<code src="./demo/warning-only.tsx">非阻塞校验</code>
<code src="./demo/useWatch.tsx">字段监听 Hooks</code>
<code src="./demo/validate-trigger.tsx">校验时机</code>
<code src="./demo/validate-only.tsx">仅校验</code>
<code src="./demo/form-item-path.tsx">字段路径前缀</code>
<code src="./demo/dynamic-form-item.tsx">动态增减表单项</code>
@ -144,6 +145,7 @@ const validateMessages = {
| tooltip | 配置提示信息 | ReactNode \| [TooltipProps & { icon: ReactNode }](/components/tooltip-cn#api) | - | 4.7.0 |
| trigger | 设置收集字段值变更的时机。点击[此处](#components-form-demo-customized-form-controls)查看示例 | string | `onChange` | |
| validateFirst | 当某一规则校验不通过时,是否停止剩下的规则的校验。设置 `parallel` 时会并行校验 | boolean \| `parallel` | false | `parallel`: 4.5.0 |
| validateDebounce | 设置防抖,延迟毫秒数后进行校验 | number | - | 5.9.0 |
| validateStatus | 校验状态,如不设置,则会根据校验规则自动生成,可选:'success' 'warning' 'error' 'validating' | string | - | |
| validateTrigger | 设置字段校验的时机 | string \| string\[] | `onChange` | |
| valuePropName | 子节点的值的属性,如 Switch、Checkbox 的是 `checked`。该属性为 `getValueProps` 的封装,自定义 `getValueProps` 后会失效 | string | `value` | |

View File

@ -129,7 +129,7 @@
"rc-dialog": "~9.2.0",
"rc-drawer": "~6.4.1",
"rc-dropdown": "~4.1.0",
"rc-field-form": "~1.37.0",
"rc-field-form": "~1.38.0",
"rc-image": "~7.2.0",
"rc-input": "~1.1.0",
"rc-input-number": "~8.0.2",