feat: form item dep (#25408)

* feat: warnings

* feat: deps work on FormItem with render props

* chore: add details warning info

* chore

* chore: rerun ci

* chore: revert

* docs

* docs
This commit is contained in:
07akioni 2020-07-03 16:25:29 +08:00 committed by GitHub
parent 193c16d6f1
commit 27b6ba6947
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 156 additions and 6 deletions

View File

@ -299,14 +299,20 @@ function FormItem(props: FormItemProps): React.ReactElement {
};
let childNode: React.ReactNode = null;
devWarning(
!(shouldUpdate && dependencies),
'Form.Item',
"`shouldUpdate` and `dependencies` shouldn't be used together. See https://ant.design/components/form/#dependencies.",
);
if (Array.isArray(children) && hasName) {
devWarning(false, 'Form.Item', '`children` is array of render props cannot have `name`.');
childNode = children;
} else if (isRenderProps && (!shouldUpdate || hasName)) {
} else if (isRenderProps && (!(shouldUpdate || dependencies) || hasName)) {
devWarning(
!!shouldUpdate,
!!(shouldUpdate || dependencies),
'Form.Item',
'`children` of render props only work with `shouldUpdate`.',
'`children` of render props only work with `shouldUpdate` or `dependencies`.',
);
devWarning(
!hasName,
@ -356,7 +362,7 @@ function FormItem(props: FormItemProps): React.ReactElement {
{cloneElement(children, childProps)}
</MemoInput>
);
} else if (isRenderProps && shouldUpdate && !hasName) {
} else if (isRenderProps && (shouldUpdate || dependencies) && !hasName) {
childNode = (children as RenderChildren)(context);
} else {
devWarning(

View File

@ -1449,6 +1449,81 @@ exports[`renders ./components/form/demo/disabled-input-debug.md correctly 1`] =
</form>
`;
exports[`renders ./components/form/demo/dep-debug.md correctly 1`] = `
<form
class="ant-form ant-form-horizontal"
id="debug"
>
0
<div
class="ant-row ant-form-item"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
for="debug_debug1"
title="debug1"
>
debug1
</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"
>
<input
class="ant-input"
id="debug_debug1"
type="text"
value="debug1"
/>
</div>
</div>
</div>
</div>
<div
class="ant-row ant-form-item"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
for="debug_debug2"
title="debug2"
>
debug2
</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"
>
<input
class="ant-input"
id="debug_debug2"
type="text"
value="debug2"
/>
</div>
</div>
</div>
</div>
</form>
`;
exports[`renders ./components/form/demo/dynamic-form-item.md correctly 1`] = `
<form
class="ant-form ant-form-horizontal"

View File

@ -66,7 +66,19 @@ describe('Form', () => {
</Form>,
);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Form.Item] `children` of render props only work with `shouldUpdate`.',
'Warning: [antd: Form.Item] `children` of render props only work with `shouldUpdate` or `dependencies`.',
);
});
it("`shouldUpdate` shouldn't work with `dependencies`", () => {
mount(
<Form>
<Form.Item shouldUpdate dependencies={[]}>
{() => null}
</Form.Item>
</Form>,
);
expect(errorSpy).toHaveBeenCalledWith(
"Warning: [antd: Form.Item] `shouldUpdate` and `dependencies` shouldn't be used together. See https://ant.design/components/form/#dependencies.",
);
});
it('`name` should not work with render props', () => {

View File

@ -0,0 +1,49 @@
---
order: 99
title:
zh-CN: Dep Debug
en-US: Dep Debug
---
## zh-CN
Buggy!
## en-US
Buggy!
```tsx
import { Form, Input } from 'antd';
let acc = 0;
const Demo = () => {
const [form] = Form.useForm();
return (
<Form
form={form}
name="debug"
initialValues={{
debug1: 'debug1',
debug2: 'debug2',
}}
>
<Form.Item noStyle dependencies={['debug1']}>
{() => {
return acc++;
// return <pre>{JSON.stringify(form.getFieldsValue(), null, 2)}</pre>;
}}
</Form.Item>
<Form.Item label="debug1" name="debug1">
<Input />
</Form.Item>
<Form.Item label="debug2" name="debug2">
<Input />
</Form.Item>
</Form>
);
};
ReactDOM.render(<Demo />, mountNode);
```

View File

@ -109,6 +109,10 @@ After wrapped by `Form.Item` with `name` property, `value`(or other property def
Used when there are dependencies between fields. If a field has the `dependencies` prop, this field will automatically trigger updates and validations when upstream is updated. A common scenario is a user registration form with "password" and "confirm password" fields. The "Confirm Password" validation depends on the "Password" field. After setting `dependencies`, the "Password" field update will re-trigger the validation of "Check Password". You can refer [examples](#components-form-demo-register).
`dependencies` shouldn't be used together with `shouldUpdate`. Since it may cause chaos in updating logic.
`dependencies` supports `Form.Item` with render props children since `4.5.0`.
### shouldUpdate
Form updates only the modified field-related components for performance optimization purposes by incremental update. In most cases, you only need to write code or do validation with the [`dependencies`](#dependencies) property. In some specific cases, such as when a new field option appears with a filed value changed, or you just want to keep some area updating by form update, you can modify the update logic of Form.Item via the `shouldUpdate`.

View File

@ -110,6 +110,10 @@ const validateMessages = {
当字段间存在依赖关系时使用。如果一个字段设置了 `dependencies` 属性。那么它所依赖的字段更新时,该字段将自动触发更新与校验。一种常见的场景,就是注册用户表单的“密码”与“确认密码”字段。“确认密码”校验依赖于“密码”字段,设置 `dependencies` 后,“密码”字段更新会重新触发“校验密码”的校验逻辑。你可以参考[具体例子](#components-form-demo-register)。
`dependencies` 不应和 `shouldUpdate` 一起使用,因为这可能带来更新逻辑的混乱。
`4.5.0` 版本开始,`dependencies` 支持使用 render props 类型 children 的 `Form.Item`
### shouldUpdate
Form 通过增量更新方式,只更新被修改的字段相关组件以达到性能优化目的。大部分场景下,你只需要编写代码或者与 [`dependencies`](#dependencies) 属性配合校验即可。而在某些特定场景,例如修改某个字段值后出现新的字段选项、或者纯粹希望表单任意变化都对某一个区域进行渲染。你可以通过 `shouldUpdate` 修改 Form.Item 的更新逻辑。

View File

@ -121,7 +121,7 @@
"rc-dialog": "~8.0.0",
"rc-drawer": "~4.1.0",
"rc-dropdown": "~3.1.2",
"rc-field-form": "~1.6.0",
"rc-field-form": "~1.7.0",
"rc-input-number": "~5.1.0",
"rc-mentions": "~1.3.0",
"rc-menu": "~8.3.0",