Browse Source
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
pull/25488/head
07akioni
4 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with
156 additions and
6 deletions
components/form/FormItem.tsx
components/form/__tests__/__snapshots__/demo.test.js.snap
components/form/__tests__/index.test.js
components/form/demo/dep-debug.md
components/form/index.en-US.md
components/form/index.zh-CN.md
package.json
@ -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 (
@ -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"
@ -66,7 +66,19 @@ describe('Form', () => {
< / F o r m > ,
) ;
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 }
< / F o r m . I t e m >
< / F o r m > ,
) ;
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' , ( ) => {
@ -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);
```
@ -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` .
@ -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 的更新逻辑。
@ -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" ,