Skip to content

Comments

fix(useForm): recompute isValid after reset when values update asynchronously#13126

Merged
bluebill1049 merged 2 commits intoreact-hook-form:masterfrom
a28689604:fix/isvalid-after-async-values-reset
Nov 9, 2025
Merged

fix(useForm): recompute isValid after reset when values update asynchronously#13126
bluebill1049 merged 2 commits intoreact-hook-form:masterfrom
a28689604:fix/isvalid-after-async-values-reset

Conversation

@a28689604
Copy link
Contributor

@a28689604 a28689604 commented Nov 4, 2025

Proposed Changes

Problem:

When props.values are set asynchronously, formState.isValid wasn’t recalculated because reset() sets control._state.mount = true, so the useForm mount effect that calls _setValid() no longer runs.

Root cause flow:

  1. values are set asynchronously.
  2. useForm effect runs due to props.values change:

React.useEffect(() => {
if (props.values && !deepEqual(props.values, _values.current)) {
control._reset(props.values, {
keepFieldsRef: true,
...control._options.resetOptions,
});
_values.current = props.values;
updateFormState((state) => ({ ...state }));
} else {
control._resetDefaultValues();
}
}, [control, props.values]);

  1. _reset() is called.
  2. After reset, control._state.mount becomes true following the changes in fix: watch() returning undefined immediately after reset() - Issue #13088 #13091, so the mount effect below doesn’t call _setValid() anymore:
    React.useEffect(() => {
    if (!control._state.mount) {
    control._setValid();
    control._state.mount = true;
    }

Fix:

Recompute validity at the end of _reset() while respecting keep-state options.

Fixes #13123

Type of change

  • Bug fix (non-breaking change which fixes an issue)

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

…ronously

- Call _setValid() at the end of _reset() unless keepIsValid is set.
- Ensures formState.isValid updates correctly when props.values change asynchronously.

Signed-off-by: Eric Chen <[email protected]>
defaultValues: _defaultValues as FormState<TFieldValues>['defaultValues'],
});

!keepStateOptions.keepIsValid && _setValid();
Copy link
Member

Choose a reason for hiding this comment

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

Can this logic move to the hook level?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I’ve moved the code to useForm, and it now runs after the reset is completed.

- Call _setValid() in useForm when resetOptions.keepIsValid is false.
@a28689604
Copy link
Contributor Author

@bluebill1049
I found another issue, keepIsDirty doesn’t work as expected after version 7.60.0-next.0. It behaves correctly in 7.59.0.

Please check this example: when clicking the button, the form resets with invalid data, but isValid should remain true; instead, it changes.
https://codesandbox.io/p/sandbox/tender-ace-4434lg

Could you confirm if this is unintended behavior? If so, I’ll work on a fix and add a test file to cover this case.

@bluebill1049
Copy link
Member

yea keep dirty shouldn't affect isValid flag

@bluebill1049 bluebill1049 merged commit fb6423f into react-hook-form:master Nov 9, 2025
6 checks passed
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.

issue: Form doesn't automatically revalidate when values prop changes

2 participants