Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v2] Form-level validation runs on old values #1977

Closed
gggdomi opened this issue Oct 31, 2019 · 1 comment · Fixed by #2025
Closed

[v2] Form-level validation runs on old values #1977

gggdomi opened this issue Oct 31, 2019 · 1 comment · Fixed by #2025

Comments

@gggdomi
Copy link

gggdomi commented Oct 31, 2019

🐛 Bug report

Current Behavior

Using setValues with a form-level <Formik validate> will call validation function on the previous state.

Expected behavior

Validation should be called on the newly set values. Works as expected with Formik 1.5.8

Reproducible example

Very minimal example : https://codesandbox.io/s/formik-codesandbox-template-zm8tc

Just press "Set Values" button and watch console : Validation called on : "old name" appears instead of expected Validation called on : "John"

Suggested solution(s)

Weirdly, setValues and setFieldValue implementation are very similar (see below), but only the former is broken

formik/src/Formik.tsx

Lines 516 to 521 in d90149e

const setValues = useEventCallback((values: Values) => {
dispatch({ type: 'SET_VALUES', payload: values });
return validateOnChange
? validateFormWithLowPriority(state.values)
: Promise.resolve();
});

formik/src/Formik.tsx

Lines 533 to 546 in d90149e

const setFieldValue = useEventCallback(
(field: string, value: any, shouldValidate: boolean = true) => {
dispatch({
type: 'SET_FIELD_VALUE',
payload: {
field,
value,
},
});
return validateOnChange && shouldValidate
? validateFormWithLowPriority(setIn(state.values, field, value))
: Promise.resolve();
}
);

Related problem ?

Calling setFieldValue multiple times has a different behaviour regarding validation since v2.

Minimal example : https://codesandbox.io/s/formik-codesandbox-template-f2huz

Just press "Set Values" button and watch console :

Validation called on : {a: 1, b: 0}
Validation called on : {a: 0, b: 2}

In Formik 1.5.8, the output (which feels better to me) would be :

Validation called on : {a: 1, b: 2}
Validation called on : {a: 1, b: 2}

Your environment

Software Version(s)
Formik 2.0.3
React 16.11.0
TypeScript -
Browser Chrome 78
npm/Yarn Yarn 1.19.0
Operating System Mac OS 10.15
@anothertempore
Copy link

anothertempore commented Nov 11, 2019

I think the reason for this problem is that dispatch is an async function, so there is no way to know when the state has been updated.

For the setValue method, I think we can easily pass the values parameter into validateFormWithLowPriority method, but for the setFieldValue method, I have no idea how to deal with it.

Related issues:

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 a pull request may close this issue.

2 participants