Skip to content

Commit 90a87e8

Browse files
authored
fix: preserve sibling values when nested list changes (#779)
* test: add mixed field list onValuesChange case * fix: preserve sibling values for nested list changes * test: cover nested list remove onValuesChange
1 parent 69b271e commit 90a87e8

File tree

2 files changed

+91
-7
lines changed

2 files changed

+91
-7
lines changed

src/hooks/useForm.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { merge } from '@rc-component/util/lib/utils/set';
2-
import { mergeWith } from '@rc-component/util';
32
import warning from '@rc-component/util/lib/warning';
43
import * as React from 'react';
54
import { HOOK_MARK } from '../FieldContext';
@@ -779,14 +778,9 @@ export class FormStore {
779778
const { onValuesChange } = this.callbacks;
780779

781780
if (onValuesChange) {
782-
const fieldEntity = this.getFieldsMap(true).get(namePath);
783781
const changedValues = cloneByNamePathList(this.store, [namePath]);
784782
const allValues = this.getFieldsValue();
785-
// Merge changedValues into allValues to ensure allValues contains the latest changes
786-
const mergedAllValues = mergeWith([allValues, changedValues], {
787-
// When value is array, it means trigger by Form.List which should replace directly
788-
prepareArray: current => (fieldEntity?.isList() ? [] : [...(current || [])]),
789-
});
783+
const mergedAllValues = setValue(allValues, namePath, getValue(changedValues, namePath));
790784
onValuesChange(changedValues, mergedAllValues);
791785
}
792786

tests/dependencies.test.tsx

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,94 @@ describe('Form.Dependencies', () => {
302302
await changeValue(getInput(container), '1');
303303
matchError(container, false);
304304
});
305+
306+
it('mixed field list should not missing value with onValuesChange', () => {
307+
const onValuesChange = jest.fn();
308+
309+
const { container } = render(
310+
<Form
311+
initialValues={{ rules: [{ name: 'test', triggers: [] }] }}
312+
onValuesChange={onValuesChange}
313+
>
314+
<Form.List name="rules">
315+
{fields =>
316+
fields.map(field => (
317+
<div key={field.key}>
318+
<Field {...field} name={[field.name, 'name']}>
319+
<Input />
320+
</Field>
321+
322+
<Form.List name={[field.name, 'triggers']}>
323+
{(triggerFields, { add }) => (
324+
<>
325+
{triggerFields.map(triggerField => (
326+
<Field {...triggerField} key={triggerField.key}>
327+
<Input />
328+
</Field>
329+
))}
330+
<button type="button" onClick={() => add('trigger_1')}>
331+
Add trigger
332+
</button>
333+
</>
334+
)}
335+
</Form.List>
336+
</div>
337+
))
338+
}
339+
</Form.List>
340+
</Form>,
341+
);
342+
343+
fireEvent.click(container.querySelector('button')!);
344+
345+
expect(onValuesChange).toHaveBeenLastCalledWith(
346+
expect.anything(),
347+
{ rules: [{ name: 'test', triggers: ['trigger_1'] }] },
348+
);
349+
});
350+
351+
it('mixed field list remove should not missing value with onValuesChange', () => {
352+
const onValuesChange = jest.fn();
353+
354+
const { container } = render(
355+
<Form
356+
initialValues={{ rules: [{ name: 'test', triggers: ['trigger_1', 'trigger_2'] }] }}
357+
onValuesChange={onValuesChange}
358+
>
359+
<Form.List name="rules">
360+
{fields =>
361+
fields.map(field => (
362+
<div key={field.key}>
363+
<Field {...field} name={[field.name, 'name']}>
364+
<Input />
365+
</Field>
366+
367+
<Form.List name={[field.name, 'triggers']}>
368+
{(triggerFields, { remove }) => (
369+
<>
370+
{triggerFields.map(triggerField => (
371+
<Field {...triggerField} key={triggerField.key}>
372+
<Input />
373+
</Field>
374+
))}
375+
<button type="button" onClick={() => remove(0)}>
376+
Remove trigger
377+
</button>
378+
</>
379+
)}
380+
</Form.List>
381+
</div>
382+
))
383+
}
384+
</Form.List>
385+
</Form>,
386+
);
387+
388+
fireEvent.click(container.querySelector('button')!);
389+
390+
expect(onValuesChange).toHaveBeenLastCalledWith(
391+
expect.anything(),
392+
{ rules: [{ name: 'test', triggers: ['trigger_2'] }] },
393+
);
394+
});
305395
});

0 commit comments

Comments
 (0)