diff --git a/.changeset/fix-5076-resetform-fieldarray.md b/.changeset/fix-5076-resetform-fieldarray.md new file mode 100644 index 000000000..9b4172b75 --- /dev/null +++ b/.changeset/fix-5076-resetform-fieldarray.md @@ -0,0 +1,5 @@ +--- +"vee-validate": patch +--- + +Fix resetForm not properly resetting fieldArray after the first reset when used with Form component (#5076) diff --git a/packages/vee-validate/src/useForm.ts b/packages/vee-validate/src/useForm.ts index f5e7329b8..8fb6f31ab 100644 --- a/packages/vee-validate/src/useForm.ts +++ b/packages/vee-validate/src/useForm.ts @@ -684,6 +684,9 @@ export function useForm< setFieldValue(path as Path, fields[path], false); }); + // regenerate the arrays when the form values change + fieldArrays.forEach(f => f && f.reset()); + if (shouldValidate) { validate(); } diff --git a/packages/vee-validate/tests/useFieldArray.spec.ts b/packages/vee-validate/tests/useFieldArray.spec.ts index 73bd05b8a..db201d2c0 100644 --- a/packages/vee-validate/tests/useFieldArray.spec.ts +++ b/packages/vee-validate/tests/useFieldArray.spec.ts @@ -577,3 +577,59 @@ test('errors are available to the newly inserted items', async () => { await flushPromises(); expect(spanAt(1).textContent).toBeTruthy(); }); + +test('resetForm with force: true resets useFieldArray correctly on subsequent resets (#5076)', async () => { + let arr!: FieldArrayContext; + + const AddButton = defineComponent({ + setup() { + arr = useFieldArray('options'); + + return { + fields: arr.fields, + }; + }, + template: ` +
+

{{ field.value }}

+
+ `, + }); + + mountWithHoc({ + components: { + AddButton, + }, + template: ` + + + {{ values.options?.length }} + + + + `, + }); + + await flushPromises(); + expect(arr.fields.value).toHaveLength(2); + + // Add an item + arr.push('C'); + await flushPromises(); + expect(arr.fields.value).toHaveLength(3); + + // First reset with force: true + (document.querySelector('#reset') as HTMLButtonElement).click(); + await flushPromises(); + expect(arr.fields.value).toHaveLength(2); + + // Add another item after reset + arr.push('D'); + await flushPromises(); + expect(arr.fields.value).toHaveLength(3); + + // Second reset with force: true — this is the one that fails without the fix + (document.querySelector('#reset') as HTMLButtonElement).click(); + await flushPromises(); + expect(arr.fields.value).toHaveLength(2); +});