diff --git a/src/hooks/useForm.ts b/src/hooks/useForm.ts index ebbefd92..c660f9a2 100644 --- a/src/hooks/useForm.ts +++ b/src/hooks/useForm.ts @@ -1,5 +1,4 @@ import { merge } from '@rc-component/util/lib/utils/set'; -import { mergeWith } from '@rc-component/util'; import warning from '@rc-component/util/lib/warning'; import * as React from 'react'; import { HOOK_MARK } from '../FieldContext'; @@ -779,14 +778,9 @@ export class FormStore { const { onValuesChange } = this.callbacks; if (onValuesChange) { - const fieldEntity = this.getFieldsMap(true).get(namePath); const changedValues = cloneByNamePathList(this.store, [namePath]); const allValues = this.getFieldsValue(); - // Merge changedValues into allValues to ensure allValues contains the latest changes - const mergedAllValues = mergeWith([allValues, changedValues], { - // When value is array, it means trigger by Form.List which should replace directly - prepareArray: current => (fieldEntity?.isList() ? [] : [...(current || [])]), - }); + const mergedAllValues = setValue(allValues, namePath, getValue(changedValues, namePath)); onValuesChange(changedValues, mergedAllValues); } diff --git a/tests/dependencies.test.tsx b/tests/dependencies.test.tsx index 8ba8260d..d81533b0 100644 --- a/tests/dependencies.test.tsx +++ b/tests/dependencies.test.tsx @@ -302,4 +302,94 @@ describe('Form.Dependencies', () => { await changeValue(getInput(container), '1'); matchError(container, false); }); + + it('mixed field list should not missing value with onValuesChange', () => { + const onValuesChange = jest.fn(); + + const { container } = render( +
+ + {fields => + fields.map(field => ( +
+ + + + + + {(triggerFields, { add }) => ( + <> + {triggerFields.map(triggerField => ( + + + + ))} + + + )} + +
+ )) + } +
+
, + ); + + fireEvent.click(container.querySelector('button')!); + + expect(onValuesChange).toHaveBeenLastCalledWith( + expect.anything(), + { rules: [{ name: 'test', triggers: ['trigger_1'] }] }, + ); + }); + + it('mixed field list remove should not missing value with onValuesChange', () => { + const onValuesChange = jest.fn(); + + const { container } = render( +
+ + {fields => + fields.map(field => ( +
+ + + + + + {(triggerFields, { remove }) => ( + <> + {triggerFields.map(triggerField => ( + + + + ))} + + + )} + +
+ )) + } +
+
, + ); + + fireEvent.click(container.querySelector('button')!); + + expect(onValuesChange).toHaveBeenLastCalledWith( + expect.anything(), + { rules: [{ name: 'test', triggers: ['trigger_2'] }] }, + ); + }); });