fix: Form with multiple same error render error (#51636)

* fix: key warning

* test: add test case
This commit is contained in:
二货爱吃白萝卜 2024-11-14 17:09:23 +08:00 committed by GitHub
parent 8f99da85ac
commit e61211c06b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 69 additions and 2 deletions

View File

@ -78,6 +78,17 @@ const ErrorList: React.FC<ErrorListProps> = ({
]; ];
}, [help, helpStatus, debounceErrors, debounceWarnings]); }, [help, helpStatus, debounceErrors, debounceWarnings]);
const filledKeyFullKeyList = React.useMemo<ErrorEntity[]>(() => {
const keysCount: Record<string, number> = {};
fullKeyList.forEach(({ key }) => {
keysCount[key] = (keysCount[key] || 0) + 1;
});
return fullKeyList.map((entity, index) => ({
...entity,
key: keysCount[entity.key] > 1 ? `${entity.key}-fallback-${index}` : entity.key,
}));
}, [fullKeyList]);
const helpProps: { id?: string } = {}; const helpProps: { id?: string } = {};
if (fieldId) { if (fieldId) {
@ -88,7 +99,7 @@ const ErrorList: React.FC<ErrorListProps> = ({
<CSSMotion <CSSMotion
motionDeadline={collapseMotion.motionDeadline} motionDeadline={collapseMotion.motionDeadline}
motionName={`${prefixCls}-show-help`} motionName={`${prefixCls}-show-help`}
visible={!!fullKeyList.length} visible={!!filledKeyFullKeyList.length}
onVisibleChanged={onVisibleChanged} onVisibleChanged={onVisibleChanged}
> >
{(holderProps) => { {(holderProps) => {
@ -109,7 +120,7 @@ const ErrorList: React.FC<ErrorListProps> = ({
role="alert" role="alert"
> >
<CSSMotionList <CSSMotionList
keys={fullKeyList} keys={filledKeyFullKeyList}
{...initCollapseMotion(prefixCls)} {...initCollapseMotion(prefixCls)}
motionName={`${prefixCls}-show-help-item`} motionName={`${prefixCls}-show-help-item`}
component={false} component={false}

View File

@ -2459,4 +2459,60 @@ describe('Form', () => {
fireEvent.click(container.querySelector('input')!); fireEvent.click(container.querySelector('input')!);
expect(container.querySelector('input')?.checked).toBeTruthy(); expect(container.querySelector('input')?.checked).toBeTruthy();
}); });
it('not warning for react key', async () => {
const MockInput = (props: { onChange?: (value: number[]) => void }) => (
<Input
onChange={({ target: { value } }) => {
props.onChange?.(value.split(',').map(Number));
}}
/>
);
const { container } = render(
<Form>
<Form.Item>
<Form.Item
name="test"
rules={[
{
type: 'array',
defaultField: {
type: 'number',
min: 10,
message: 'LESS_THAN_10',
},
},
]}
>
<MockInput />
</Form.Item>
</Form.Item>
</Form>,
);
function expectErrors(errors: string[]) {
expect(container.querySelectorAll('.ant-form-item-explain-error')).toHaveLength(
errors.length,
);
errors.forEach((error, index) => {
expect(container.querySelectorAll('.ant-form-item-explain-error')[index]).toHaveTextContent(
error,
);
});
}
// user type something and clear
await changeValue(0, '1');
expectErrors(['LESS_THAN_10']);
await changeValue(0, '1,1');
expectErrors(['LESS_THAN_10', 'LESS_THAN_10']);
await changeValue(0, '1');
expectErrors(['LESS_THAN_10']);
await changeValue(0, '100');
expectErrors([]);
});
}); });