Skip to content

🐞 fix(useForm): reset options that are removed from the props on re-render - #13831

Merged
bluebill1049 merged 4 commits into
react-hook-form:masterfrom
charan-rathore:fix/useform-reset-removed-options
Oct 6, 2026
Merged

bluebill1049 merged 4 commits into
react-hook-form:masterfrom
charan-rathore:fix/useform-reset-removed-options

Conversation

@charan-rathore

Copy link
Copy Markdown
Contributor

Pull Request Template

Proposed Changes

When an option is left out of the props useForm gets on a later render, the form keeps using the value from the earlier render.

For example useForm(useResolver ? { resolver } : {}): after useResolver turns false the resolver is still called on submit and its errors still block the form. The same happens with mode: going from { mode: 'onChange' } to {} keeps validating on change instead of going back to the default onSubmit.

The cause is that the options are merged into the previous ones on every render, so a key that is missing is never cleared. validate already had a special case for this.

The fix remembers which option keys were passed last render. Keys that are now missing go back to their default (mode, reValidateMode and shouldFocusError have defaults, the rest become undefined). Options passed to a form made with createFormControl are untouched, because only keys that came from useForm props are reset.

I added tests for a removed resolver and a removed mode. Both fail without the fix.

Fixes # (no issue, found while reading how the options are updated)

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes

@bluebill1049 bluebill1049 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the stale option issue is valid, but can we avoid tracking/resetting every key from UseFormProps?
Props such as values, errors, defaultValues, formControl, etc. have their own lifecycle handling in useForm, so treating every removed prop as a control._options option feels a bit too broad.
Could we limit this to the actual persistent control options that need resetting, or centralize the option update logic instead?

@charan-rathore
charan-rathore force-pushed the fix/useform-reset-removed-options branch from 653409e to b8e7378 Compare October 5, 2026 22:39
@charan-rathore

Copy link
Copy Markdown
Contributor Author

Good point, thanks - updated. The reset now skips the props that have their own lifecycle handling (values, errors, defaultValues, formControl), so only the plain control options are affected. Those are restored to their defaultOptions value when there is one (e.g. mode back to onSubmit) and cleared otherwise (e.g. a removed resolver). validate was already reset by the existing validate: props.validate line, so it is unchanged.

Both new tests still pass, and the full useForm suite is green (632 tests).

@bluebill1049

Copy link
Copy Markdown
Member

Thanks, this is safer than the previous version. I still think tracking all prop keys and excluding special cases is a bit broad though. It means future UseFormProps with their own lifecycle need to be manually added to this exclusion list. Could we make this opt-in instead and explicitly define the control options that should be synchronized/reset? That would also avoid needing the Record<string, unknown> lookup against defaultOptions.

@charan-rathore

Copy link
Copy Markdown
Contributor Author

Done - it is opt-in now. There is an explicit SYNCED_OPTIONS list (mode, reValidateMode, shouldFocusError, resolver, criteriaMode, delayError, shouldUnregister, shouldUseNativeValidation, context), and only a listed option that was present in the previous options and is gone from the props gets reset: to its defaultOptions value when it has one, cleared otherwise. No prop-key tracking and no blanket Record lookup anymore; new UseFormProps stay out of this unless someone adds them to the list deliberately. useForm suite and tsc are green.

@charan-rathore
charan-rathore force-pushed the fix/useform-reset-removed-options branch from b8e7378 to 54c495e Compare October 5, 2026 22:49
bluebill1049
bluebill1049 previously approved these changes Oct 5, 2026

@bluebill1049 bluebill1049 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Replace SYNCED_OPTIONS with RESET_OPTIONS for default handling.
@bluebill1049

Copy link
Copy Markdown
Member

I did a bit of cleanup there. Could you help me re-run Prettier? Thanks!

Signed-off-by: Charan Rathore <[email protected]>
@charan-rathore

Copy link
Copy Markdown
Contributor Author

Done, reran Prettier on the touched files and pushed the formatting fix. Thanks!

@bluebill1049
bluebill1049 merged commit 36e5329 into react-hook-form:master Oct 6, 2026
6 checks passed
@charan-rathore
charan-rathore deleted the fix/useform-reset-removed-options branch October 6, 2026 00:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants