Skip to content

Commit 0987b74

Browse files
logaretmclaude
andcommitted
fix: resetForm properly resets fieldArray on subsequent resets (#5076)
When resetForm was called with { force: true }, it used forceSetValues which did not reset field arrays, unlike the non-force path through setValues. This caused useFieldArray fields to not properly sync after the first reset. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7d8cc52 commit 0987b74

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"vee-validate": patch
3+
---
4+
5+
Fix resetForm not properly resetting fieldArray after the first reset when used with Form component (#5076)

packages/vee-validate/src/useForm.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,9 @@ export function useForm<
684684
setFieldValue(path as Path<TValues>, fields[path], false);
685685
});
686686

687+
// regenerate the arrays when the form values change
688+
fieldArrays.forEach(f => f && f.reset());
689+
687690
if (shouldValidate) {
688691
validate();
689692
}

packages/vee-validate/tests/useFieldArray.spec.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,3 +577,59 @@ test('errors are available to the newly inserted items', async () => {
577577
await flushPromises();
578578
expect(spanAt(1).textContent).toBeTruthy();
579579
});
580+
581+
test('resetForm with force: true resets useFieldArray correctly on subsequent resets (#5076)', async () => {
582+
let arr!: FieldArrayContext;
583+
584+
const AddButton = defineComponent({
585+
setup() {
586+
arr = useFieldArray('options');
587+
588+
return {
589+
fields: arr.fields,
590+
};
591+
},
592+
template: `
593+
<div>
594+
<p v-for="(field, idx) in fields" :key="field.key">{{ field.value }}</p>
595+
</div>
596+
`,
597+
});
598+
599+
mountWithHoc({
600+
components: {
601+
AddButton,
602+
},
603+
template: `
604+
<VForm v-slot="{ resetForm, values }" :initial-values="{ options: ['A', 'B'] }">
605+
<AddButton />
606+
<span id="count">{{ values.options?.length }}</span>
607+
<button id="reset" type="button" @click="resetForm({ values: { options: ['A', 'B'] } }, { force: true })">Reset</button>
608+
<button id="add" type="button" @click="() => {}">Add</button>
609+
</VForm>
610+
`,
611+
});
612+
613+
await flushPromises();
614+
expect(arr.fields.value).toHaveLength(2);
615+
616+
// Add an item
617+
arr.push('C');
618+
await flushPromises();
619+
expect(arr.fields.value).toHaveLength(3);
620+
621+
// First reset with force: true
622+
(document.querySelector('#reset') as HTMLButtonElement).click();
623+
await flushPromises();
624+
expect(arr.fields.value).toHaveLength(2);
625+
626+
// Add another item after reset
627+
arr.push('D');
628+
await flushPromises();
629+
expect(arr.fields.value).toHaveLength(3);
630+
631+
// Second reset with force: true — this is the one that fails without the fix
632+
(document.querySelector('#reset') as HTMLButtonElement).click();
633+
await flushPromises();
634+
expect(arr.fields.value).toHaveLength(2);
635+
});

0 commit comments

Comments
 (0)