|
1 | | -import React, { useCallback, useEffect, useImperativeHandle, useRef } from 'react'; |
| 1 | +import React, { useEffect, useImperativeHandle, useRef } from 'react'; |
2 | 2 | import classNames from 'classnames'; |
3 | 3 |
|
4 | 4 | import forwardRefWithStatics from '../_util/forwardRefWithStatics'; |
5 | 5 | import noop from '../_util/noop'; |
6 | 6 | import useConfig from '../hooks/useConfig'; |
7 | 7 | import useDefaultProps from '../hooks/useDefaultProps'; |
8 | | -import useLayoutEffect from '../hooks/useLayoutEffect'; |
9 | 8 | import { formDefaultProps } from './defaultProps'; |
10 | 9 | import FormContext from './FormContext'; |
11 | 10 | import FormItem from './FormItem'; |
12 | 11 | import FormList from './FormList'; |
13 | 12 | import useForm, { HOOK_MARK } from './hooks/useForm'; |
14 | 13 | import useInstance from './hooks/useInstance'; |
| 14 | +import useLastFormItem from './hooks/useLastFormItem'; |
15 | 15 | import useWatch from './hooks/useWatch'; |
16 | | -import { resolveLastFormItems } from './utils/lastFormItem'; |
17 | 16 |
|
18 | 17 | import type { StyledProps } from '../common'; |
19 | 18 | import type { TdFormProps } from './type'; |
@@ -56,67 +55,11 @@ const Form = forwardRefWithStatics( |
56 | 55 | const [form] = useForm(props.form); // 内部与外部共享 form 实例,外部不传则内部创建 |
57 | 56 | const formRef = useRef<HTMLFormElement>(null); |
58 | 57 | const formMapRef = useRef(new Map()); // 收集所有包含 name 属性 formItem 实例 |
59 | | - const formItemElementsRef = useRef(new Set<HTMLElement>()); // 收集所有参与布局的 FormItem |
60 | | - const lastFormItemsRef = useRef(new Set<HTMLElement>()); |
61 | 58 | const floatingFormDataRef = useRef({}); // 储存游离值的 formData |
62 | 59 | const mountedFieldsRef = useRef<Set<string>>(new Set()); // Form 生命周期内所有曾经被 FormItem 挂载过的字段(fullPath 序列化后的字符串) |
63 | 60 |
|
64 | 61 | const formInstance = useInstance(props, formRef, formMapRef, floatingFormDataRef, form); |
65 | | - |
66 | | - const refreshLastFormItem = useCallback(() => { |
67 | | - const formElement = formRef.current; |
68 | | - const lastClassName = `${classPrefix}-form__item--last`; |
69 | | - const nextLastItems = new Set<HTMLElement>(); |
70 | | - |
71 | | - if (layout !== 'inline' && formElement) { |
72 | | - resolveLastFormItems(formElement, formItemElementsRef.current, `${classPrefix}-form__item`).forEach((item) => { |
73 | | - nextLastItems.add(item); |
74 | | - }); |
75 | | - } |
76 | | - |
77 | | - lastFormItemsRef.current.forEach((item) => { |
78 | | - if (!nextLastItems.has(item)) item.classList.remove(lastClassName); |
79 | | - }); |
80 | | - nextLastItems.forEach((item) => { |
81 | | - if (!lastFormItemsRef.current.has(item)) item.classList.add(lastClassName); |
82 | | - }); |
83 | | - lastFormItemsRef.current = nextLastItems; |
84 | | - }, [classPrefix, layout]); |
85 | | - |
86 | | - const registerFormItem = useCallback( |
87 | | - (node: HTMLElement) => { |
88 | | - formItemElementsRef.current.add(node); |
89 | | - refreshLastFormItem(); |
90 | | - |
91 | | - return () => { |
92 | | - formItemElementsRef.current.delete(node); |
93 | | - node.classList.remove(`${classPrefix}-form__item--last`); |
94 | | - lastFormItemsRef.current.delete(node); |
95 | | - refreshLastFormItem(); |
96 | | - }; |
97 | | - }, |
98 | | - [classPrefix, refreshLastFormItem], |
99 | | - ); |
100 | | - |
101 | | - useLayoutEffect(() => { |
102 | | - const formElement = formRef.current; |
103 | | - if (!formElement) return; |
104 | | - |
105 | | - refreshLastFormItem(); |
106 | | - |
107 | | - const observer = new MutationObserver(refreshLastFormItem); |
108 | | - observer.observe(formElement, { childList: true, subtree: true }); |
109 | | - |
110 | | - const resizeObserver = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(refreshLastFormItem); |
111 | | - resizeObserver?.observe(formElement); |
112 | | - |
113 | | - return () => { |
114 | | - observer.disconnect(); |
115 | | - resizeObserver?.disconnect(); |
116 | | - lastFormItemsRef.current.forEach((item) => item.classList.remove(`${classPrefix}-form__item--last`)); |
117 | | - lastFormItemsRef.current.clear(); |
118 | | - }; |
119 | | - }, [classPrefix, refreshLastFormItem]); |
| 62 | + const registerFormItem = useLastFormItem(formRef, layout, classPrefix); |
120 | 63 |
|
121 | 64 | useImperativeHandle(ref, () => formInstance); |
122 | 65 | Object.assign(form, { ...formInstance }); |
|
0 commit comments