Skip to content
Draft
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
9 changes: 4 additions & 5 deletions src/form/BaseForm/BaseForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -390,13 +390,12 @@ function BaseFormComponents<T = Record<string, any>, U = Record<string, any>>(
nameList,
);
},
/**
/**
*验字段后返回格式化之后的所有数据
* 验字段后返回格式化之后的所有数据
* @param nameList (string|number)[]
* @param omitNilParam boolean
* @returns T
*
*
* @example validateFieldsReturnFormatValue -> {a:{b:value}}
*/
validateFieldsReturnFormatValue: async (
Expand Down Expand Up @@ -493,7 +492,7 @@ function BaseFormComponents<T = Record<string, any>, U = Record<string, any>>(
return contentRender(wrapItems as any, submitterNode, formRef.current);
}
return wrapItems;
}, [grid, RowWrapper, items, contentRender, submitterNode]);
}, [grid, RowWrapper, items, contentRender, submitterNode, formRef]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Adding formRef to the dependency array of useMemo is unnecessary and potentially misleading. formRef is a ref object created via useRef within the component, so its reference is stable and will not trigger a re-computation of the memoized value. Furthermore, adding a ref object to dependencies does not solve "stale snapshot" issues because useMemo does not track changes to the .current property. If the intent is to ensure the latest form instance is used, accessing formRef.current inside the factory is sufficient, but it won't trigger updates if the ref is updated after the initial render.

Suggested change
}, [grid, RowWrapper, items, contentRender, submitterNode, formRef]);
}, [grid, RowWrapper, items, contentRender, submitterNode]);


const preInitialValues = usePrevious(props.initialValues);

Expand Down Expand Up @@ -595,7 +594,7 @@ function BaseFormComponents<T = Record<string, any>, U = Record<string, any>>(
return transformedKey ? transformedKey : {};
},
};
}, [omitNil, transformKey, formRef.current]);
}, [omitNil, transformKey, propsFormRef]);
useEffect(() => {
const finalValues = transformKey(
formRef.current?.getFieldsValue?.(true),
Expand Down
14 changes: 6 additions & 8 deletions src/form/components/FormItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,18 @@ const WithValueFomFiledProps: React.FC<
);
});

const childFieldProps = React.isValidElement(filedChildren)
? (filedChildren.props as Record<string, any>)?.fieldProps
: undefined;

const omitOnBlurAndOnChangeProps = useDeepCompareMemo(
() =>
omit(
// @ts-ignore
filedChildren?.props?.fieldProps || {},
['onBlur', 'onChange'],
),
[
omit(
// @ts-ignore
filedChildren?.props?.fieldProps || {},
childFieldProps || {},
['onBlur', 'onChange'],
),
],
[childFieldProps],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The change to the dependency array of omitOnBlurAndOnChangeProps introduces a performance regression. By using [childFieldProps] instead of the omitted object, the useDeepCompareMemo will now trigger a re-computation whenever onBlur or onChange change (which are often unstable inline functions in React forms). The previous implementation correctly ignored these event handlers by omitting them before the deep comparison, ensuring that only changes to other field props would trigger a re-render of the child component.

Suggested change
[childFieldProps],
[omit(childFieldProps || {}, ['onBlur', 'onChange'])],

);
const propsValuePropName = formFieldProps[valuePropName];

Expand Down
25 changes: 16 additions & 9 deletions src/form/layouts/ProForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { FormProps } from 'antd';
import { Form } from 'antd';
import React from 'react';
import React, { useCallback } from 'react';
import type { CommonFormProps } from '../../BaseForm';
import { BaseForm } from '../../BaseForm';
import { EditOrReadOnlyContext } from '../../BaseForm/EditOrReadOnlyContext';
Expand All @@ -16,17 +16,24 @@ function ProForm<T = Record<string, any>>(
children?: React.ReactNode | React.ReactNode[];
},
) {
const contentRender = useCallback(
(
items: React.ReactNode[],
submitter: React.ReactNode,
_form: unknown,
) => (
<>
{items}
{submitter}
</>
),
[],
);

return (
<BaseForm
layout="vertical"
contentRender={(items, submitter) => {
return (
<>
{items}
{submitter}
</>
);
}}
contentRender={contentRender}
{...props}
/>
);
Expand Down
Loading