Skip to content

Commit fb6423f

Browse files
authored
🐞 fix(useForm): recompute isValid after reset when values update asynchronously (#13126)
* fix(useForm): recompute isValid after reset when values update asynchronously - 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]> * fix(useForm): ensure validity state is updated after reset - Call _setValid() in useForm when resetOptions.keepIsValid is false. --------- Signed-off-by: Eric Chen <[email protected]>
1 parent 4922698 commit fb6423f

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

src/__tests__/useForm/formState.test.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,48 @@ describe('formState', () => {
226226

227227
expect(await screen.findByText('invalid')).toBeVisible();
228228
});
229+
230+
it('should set isValid to true after async values provide valid data', async () => {
231+
jest.useFakeTimers();
232+
233+
const App = () => {
234+
const [value, setValue] = React.useState<{ name: string } | undefined>(
235+
undefined,
236+
);
237+
238+
React.useEffect(() => {
239+
const t = setTimeout(() => setValue({ name: 'Mike' }), 2000);
240+
return () => clearTimeout(t);
241+
}, []);
242+
243+
const {
244+
register,
245+
formState: { isValid },
246+
} = useForm<{ name: string }>({
247+
defaultValues: { name: '' },
248+
values: value ?? { name: '' },
249+
mode: 'onBlur',
250+
});
251+
252+
return (
253+
<div>
254+
<input {...register('name', { required: true })} />
255+
<p>{isValid ? 'valid' : 'invalid'}</p>
256+
</div>
257+
);
258+
};
259+
260+
render(<App />);
261+
262+
expect(screen.getByText('invalid')).toBeVisible();
263+
264+
act(() => {
265+
jest.advanceTimersByTime(2000);
266+
});
267+
268+
await waitFor(() => expect(screen.getByText('valid')).toBeVisible());
269+
jest.useRealTimers();
270+
});
229271
});
230272

231273
it('should be a proxy object that returns undefined for unknown properties', () => {

src/useForm.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ export function useForm<
157157
keepFieldsRef: true,
158158
...control._options.resetOptions,
159159
});
160+
if (!control._options.resetOptions?.keepIsValid) {
161+
control._setValid();
162+
}
160163
_values.current = props.values;
161164
updateFormState((state) => ({ ...state }));
162165
} else {

0 commit comments

Comments
 (0)