Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: form item dep #25408

Merged
merged 8 commits into from
Jul 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions components/form/FormItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down
75 changes: 75 additions & 0 deletions components/form/__tests__/__snapshots__/demo.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
14 changes: 13 additions & 1 deletion components/form/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
49 changes: 49 additions & 0 deletions components/form/demo/dep-debug.md
Original file line number Diff line number Diff line change
@@ -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);
```
4 changes: 4 additions & 0 deletions components/form/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
4 changes: 4 additions & 0 deletions components/form/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 的更新逻辑。
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down