diff --git a/.changeset/red-walls-press.md b/.changeset/red-walls-press.md new file mode 100644 index 000000000..c2ec0c169 --- /dev/null +++ b/.changeset/red-walls-press.md @@ -0,0 +1,5 @@ +--- +'formik': patch +--- + +Fixed validation on stale values diff --git a/packages/formik/src/Formik.tsx b/packages/formik/src/Formik.tsx index ea36e80d3..3b4405769 100755 --- a/packages/formik/src/Formik.tsx +++ b/packages/formik/src/Formik.tsx @@ -418,7 +418,12 @@ export function useFormik({ dispatchFn(); } }, - [props.initialErrors, props.initialStatus, props.initialTouched, props.onReset] + [ + props.initialErrors, + props.initialStatus, + props.initialTouched, + props.onReset, + ] ); React.useEffect(() => { @@ -549,7 +554,7 @@ export function useFormik({ const willValidate = shouldValidate === undefined ? validateOnBlur : shouldValidate; return willValidate - ? validateFormWithHighPriority(state.values) + ? validateFormWithHighPriority(stateRef.current.values) : Promise.resolve(); } ); @@ -560,7 +565,9 @@ export function useFormik({ const setValues = useEventCallback( (values: React.SetStateAction, shouldValidate?: boolean) => { - const resolvedValues = isFunction(values) ? values(state.values) : values; + const resolvedValues = isFunction(values) + ? values(stateRef.current.values) + : values; dispatch({ type: 'SET_VALUES', payload: resolvedValues }); const willValidate = @@ -595,7 +602,9 @@ export function useFormik({ const willValidate = shouldValidate === undefined ? validateOnChange : shouldValidate; return willValidate - ? validateFormWithHighPriority(setIn(state.values, field, resolvedValue)) + ? validateFormWithHighPriority( + setIn(stateRef.current.values, field, resolvedValue) + ) : Promise.resolve(); } ); @@ -680,7 +689,7 @@ export function useFormik({ const willValidate = shouldValidate === undefined ? validateOnBlur : shouldValidate; return willValidate - ? validateFormWithHighPriority(state.values) + ? validateFormWithHighPriority(stateRef.current.values) : Promise.resolve(); } ); diff --git a/packages/formik/test/Formik.test.tsx b/packages/formik/test/Formik.test.tsx index 864589643..777777dbe 100644 --- a/packages/formik/test/Formik.test.tsx +++ b/packages/formik/test/Formik.test.tsx @@ -1547,4 +1547,45 @@ describe('', () => { expect(InitialValuesWithNestedObject.content.items[0].cards[0].desc).toEqual('Initial Desc'); }); + + it('Should run validation on actual values when tirggering setFieldTouched after setFieldValue', async () => { + + const validationShema = { + validate: jest.fn(() => Promise.resolve({})), + } + + render( + + {formikProps => ( + { + formikProps.setFieldValue('name', e.target.value); + formikProps.setFieldTouched('name', true); + }} + /> + )} + + ); + + const input = screen.getByTestId('desc-input'); + + fireEvent.change(input, { + target: { + value: 'New Value', + }, + }); + + await waitFor(() => { + expect(validationShema.validate).toHaveBeenLastCalledWith( + { age: 30, name: 'New Value' }, + { abortEarly: false, context: { age: 30, name: 'New Value' } } + ); + }); + }); });