二货爱吃白萝卜
2 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with
49 additions and
1 deletions
.eslintrc.js
components/form/Form.tsx
components/form/__tests__/index.test.tsx
components/form/hooks/useFormWarning.ts
components/form/index.en-US.md
components/form/index.zh-CN.md
@ -189,7 +189,7 @@ module.exports = {
'unicorn/better-regex' : 2 ,
'unicorn/prefer-string-trim-start-end' : 2 ,
'unicorn/expiring-todo-comments' : 2 ,
'unicorn/no-abusive-eslint-disable' : 2 ,
'unicorn/no-abusive-eslint-disable' : 0 ,
// https://github.com/typescript-eslint/typescript-eslint/issues/2540#issuecomment-692866111
'no-use-before-define' : 0 ,
@ -15,6 +15,7 @@ import { FormContext } from './context';
import useForm , { type FormInstance } from './hooks/useForm' ;
import type { FormLabelAlign } from './interface' ;
import useFormWarning from './hooks/useFormWarning' ;
import useStyle from './style' ;
export type RequiredMark = boolean | 'optional' ;
@ -65,6 +66,11 @@ const InternalForm: React.ForwardRefRenderFunction<FormInstance, FormProps> = (p
. . . restFormProps
} = props ;
if ( process . env . NODE_ENV !== 'production' ) {
// eslint-disable-next-line react-hooks/rules-of-hooks
useFormWarning ( props ) ;
}
const mergedRequiredMark = useMemo ( ( ) = > {
if ( requiredMark !== undefined ) {
return requiredMark ;
@ -1878,4 +1878,19 @@ describe('Form', () => {
expect ( container . querySelectorAll ( 'input' ) [ 1 ] . value ) . toEqual ( '14' ) ;
expect ( errorSpy ) . not . toHaveBeenCalled ( ) ;
} ) ;
it ( 'duplicated form name' , ( ) = > {
resetWarned ( ) ;
render (
< >
< Form name = "same" / >
< Form name = "same" / >
< / > ,
) ;
expect ( errorSpy ) . toHaveBeenCalledWith (
'Warning: [antd: Form] There exist multiple Form with same `name`.' ,
) ;
} ) ;
} ) ;
@ -0,0 +1,19 @@
import { useEffect } from 'react' ;
import warning from '../../_util/warning' ;
import type { FormProps } from '../Form' ;
const names : Record < string , number > = { } ;
export default function useFormWarning ( { name } : FormProps ) {
useEffect ( ( ) = > {
if ( name ) {
names [ name ] = ( names [ name ] || 0 ) + 1 ;
warning ( names [ name ] <= 1 , 'Form' , 'There exist multiple Form with same `name`.' ) ;
return ( ) = > {
names [ name ] -= 1 ;
} ;
}
} , [ name ] ) ;
}
@ -593,6 +593,10 @@ See similar issues: [#28370](https://github.com/ant-design/ant-design/issues/283
`scrollToFirstError` and `scrollToField` deps on `id` attribute passed to form control, please make sure that it hasn't been ignored in your custom form control. Check [codesandbox ](https://codesandbox.io/s/antd-reproduction-template-forked-25nul?file=/index.js ) for solution.
### Continue, why not use `ref` to bind element?
Form can not get real DOM node when customize component not support `ref` . It will get warning in React Strict Mode if wrap with Class Component and call `findDOMNode` . So we use `id` to locate element.
### `setFieldsValue` do not trigger `onFieldsChange` or `onValuesChange` ?
It's by design. Only user interactive can trigger the change event. This design is aim to avoid call `setFieldsValue` in change event which may makes loop calling.
@ -592,6 +592,10 @@ React 中异步更新会导致受控组件交互行为异常。当用户交互
滚动依赖于表单控件元素上绑定的 `id` 字段,如果自定义控件没有将 `id` 赋到正确的元素上,这个功能将失效。你可以参考这个 [codesandbox ](https://codesandbox.io/s/antd-reproduction-template-forked-25nul?file=/index.js )。
### 继上,为何不通过 `ref` 绑定元素?
当自定义组件不支持 `ref` 时,Form 无法获取子元素真实 DOM 节点,而通过包裹 Class Component 调用 `findDOMNode` 会在 React Strict Mode 下触发警告。因而我们使用 id 来进行元素定位。
### `setFieldsValue` 不会触发 `onFieldsChange` 和 `onValuesChange` ?
是的,change 事件仅当用户交互才会触发。该设计是为了防止在 change 事件中调用 `setFieldsValue` 导致的循环问题。如果仅仅需要组件内消费,可以通过 `useWatch` 或者 `Field.renderProps` 来实现。