fix(react-hook-form): reset form state on query data change to fix useFieldArray on revisit#7452
Conversation
…eFieldArray on revisit
When navigating back to an edit form in a SPA, useFieldArray.fields was empty
on every visit after the first. The field-by-field setValue approach relied on
syncedFieldsRef which accumulated paths across navigations, causing the guard
to skip re-populating fields registered by useFieldArray on re-mount.
Replace applyValuesToFields with reset(data, { keepDirtyValues: true }). This
re-initialises the full form state including field arrays on each new query
result. The keepDirtyValues option preserves user edits that are already in
progress.
Fixes refinedev#7401
🦋 Changeset detectedLatest commit: 8415faa The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Hi @devavijha, thanks for digging into the I tried to verify the fix against a specific variant of the bug mentioned in the issue: when the component containing {!formLoading && <ComponentContainingUseFieldArray />}In that case, on a second visit I built a minimal repro with this guard pattern, confirmed the bug on unpatched Not sure if this guarded case is in scope for this PR or a separate follow-up, but wanted to flag it in case it changes the approach — e.g. needing to re-trigger |
Problem
When navigating away from an edit form and returning to it within a SPA,
useFieldArray.fieldsis empty on every visit after the first. The issue is inpackages/react-hook-form/src/useForm/index.ts.The existing approach calls
applyValuesToFields(getRegisteredFields(), data, false)which usessetValueon individual field paths and tracks synced paths insyncedFieldsRef. On re-visit:syncedFieldsRefaccumulates paths across mount/unmount cyclesuseFieldArrayare not present in the set when the effect runs again on the second visituseFieldArray.fieldsstays emptyMinimal reproduction is in the issue: https://codesandbox.io/p/sandbox/t6pxft
Fix
Replace
applyValuesToFields(getRegisteredFields(), data, false)withreset(data, { keepDirtyValues: true }).The
resetAPI from react-hook-form re-initialises the entire form state, including all field arrays, on each new query result. ThekeepDirtyValuesoption ensures that any in-progress user edits are not discarded.Changes:
resetto the destructured result fromuseHookFormapplyValuesToFieldscall insideapplyQueryValueswithreset(data, { keepDirtyValues: true })Closes #7401