The example im working with is let's say i have two drop down menus 1 & 2.
When menu1 changes, i want to reset the value of menu2. When I do this, and both fields are required, both menu1 & menu2 are invalid, even though menu1 has a value.
I am updating the value of menu2 in componentDidUpdate when formik.values.menu1 changes. I feel like calling setFieldValue('menu2,' '') should be safe.
https://gist.github.com/agmcleod/921c5798c4ba7285bc12bff8ebd6d82b
I tried to use the code sandbox templates, but yup validations werent working there for some reason.
| Software | Version(s) |
| ---------------- | ---------- |
| Formik | 2.0.6 |
| React | 16.12.0 |
| Browser | Firefox |
| npm/Yarn | yarn 1.13.0 |
| Operating System | MacOS Mojave |
Looks like I experienced the same issue today after migrating from formik _1.5_ to _2.0_
The gist is not loading for me on my network but I was having a similar issue and figured I'd mention it in case it helps someone else while upgrading....
I had multiple selects using setFieldValue but the validation always seemed to be one step behind. In my change handler I was calling setFieldValue and then setFieldTouched to touch and set the value of the field. Both of these functions trigger the validate function and it looks like the setFieldTouched function was returning last and running using the value of the field before it was updated. This showed the field as invalid even though it had a value.
In short I just updated the setFieldTouched function to not validate the form.
// Set field to touched but do not trigger validation
props.form.setFieldTouched(field.name, true, false);
@njetsy i did consider that, but i also wanted the form validating still, showing the user they need to fill out the second drop down if they already submitted.
In my case i wrapped my setFieldValue() call in a requestAnimationFrame callback, which is very much a hack.
I just found another form that's probably closer to yours where I have to clear menu 2 after selecting a new menu 1 option. When I call setFieldValue to assign the newly selected value to menu 1, it runs the yup validation successfully with the correct values. When I then call the second setFieldValue to clear menu 2, a console log within the yup validation shows the menu 1 value as still being null so it shows the field as invalid.
I'm running into a similar issue. I have a select dropdown (only 1.) and when I call form.setFieldValue(), the validation runs, but it fails for some reason until I click somewhere on the screen.
I'm also running into this after upgrading to Formik 2.x
In my case, I enabled validateOnMount and I had an onChange handler that caused a re-render on
I had a similar issue and solved it by calling setFieldTouched in a timeout.
const handleChange = (value: string) => {
formik.setFieldValue(name, value);
setTimeout(() => formik.setFieldTouched(name, true));
};
I had a similar issue and solved it by calling
setFieldTouchedin a timeout.const handleChange = (value: string) => { formik.setFieldValue(name, value); setTimeout(() => formik.setFieldTouched(name, true)); };worked me
Is there any other solution because it is ultimately a problem or not?
I am also facing the same issue with "formik": "^2.1.4".
any solution for this apart from using a timeout, which seems really hacky.
I've also run into this problem, also with formik ^2.1.4. The workaround below is working for me as well.
I had a similar issue and solved it by calling
setFieldTouchedin a timeout.const handleChange = (value: string) => { formik.setFieldValue(name, value); setTimeout(() => formik.setFieldTouched(name, true)); };
I find that I have to call validateField and setFieldTouched in my onBlur within a timeout in order to get it to work. This is so I can validate individual fields on blur. Any news on if the settimeout hack will no longer be needed at some point?
Pay attention that function setFieldValue in formik is an async function(it returns a Promise), therefore, when you want to change x field value as a result of y field , you have to put the calling for setFIeldValue on y field in a callback to the first setFieldValue call: for example:
onChange= (_, value) => {
setFIeldValue(x, value).than( (res) =>{
setFieldValue(y, /* your desired value */)
}
}
(or using async await syntax sugaring)
I had a similar issue and solved it by calling
setFieldTouchedin a timeout.const handleChange = (value: string) => { formik.setFieldValue(name, value); setTimeout(() => formik.setFieldTouched(name, true)); };worked me
Is there any other solution because it is ultimately a problem or not?
Solution without setTimeout is here:
const handleChange = async (value: string) => {
await formik.setFieldValue(name, value);
formik.setFieldTouched(name, true)
};
^ it seems the typescript definition for setFieldValue is wrong; it shows return value as void but this fix worked great for me when nothing else did.
@sjungwirth Is there a simple workaround to give typescript the correct definition? I'm running into the same issue with this.
There are PRs which are changing this type + docs but they are still not merged:
https://github.com/formium/formik/pull/2648
https://github.com/formium/formik/pull/2384
For some reason the solution without setTimeout doesn't work for me. But it works fine with delayed setFieldTouched
@sapkra @jjarcik @bswank @drudv and others using either the setTimeout method or async awaiting setFieldValue: Have you tried using formik.handleChange(key)(value) (in onChangeText) or formik.handleBlur(key)(event) (in onBlur) instead of calling setFieldTouched and setFieldValue separately? This will require having validateOnChange/validateOnBlur set to true
I was just bitten by this issue and await on setValue helped me. I was actually considering it before, but bc the docs says it's return value is "void" I didn't even bother trying it out.
I'm confused on what grounds has this issue been closed. There is no resolution or recommendation attached to closing it. I would expect to at least fix the bug in the docs or ideally provide a recommendation or even a link to the docs where this is explained.
(On a higher level, an API where one has to await for setValue before being able to call setTouched, and if not then there is no exception reported, but the setValue silently does not work, looks brittle at least, if not wrong.)
Most helpful comment
I had a similar issue and solved it by calling
setFieldTouchedin a timeout.