formik
formik copied to clipboard
call to setFieldValue and setFieldTouched at once
I have a custom component and I have to call setFieldValue to change the value in Formik state.
But the touched property to this field is not change.
I guess that I need to call setFieldTouched, am I understand it correctly? Is there any other way to set the touched value when I call to setFieldValue?
@israelKusayev if you want to act as if the field value changed normally, you can call formik.handleChange(field.name)(value)
, and all the setFieldTouched, validations, and other events will be called.
The touched is still undefined
Now that I think about it, setFieldTouched is only called on blur and during a submission attempt. Touched in formik implies that if the field isn't valid, the user will want to know. It exists because showing the user an error message while they are halfway through typing a phone number wouldn't make much sense. The best way to achieve what you're looking for is to manually call setFieldTouched. Note that you can still use handleChange
if you'd still like the normal sequence of change events to occur.
Just got this working with this:
const value = getIn(formik.values, fieldName)
const touched = getIn(formik.touched, fieldName)
const initialValue = getIn( formik.initialValues, fieldName )
useEffect(() => {
const isTouched = value === initialValue
if(touched != isTouched) formik.setFieldTouched(name, isTouched)
},[ value ])
i think if the value change, it should automatically be marked as touched.
I had this problem too and i fixed it by : await props.setFieldTouched("Discription", true) await props.setFieldTouched("Username", true)
props.handleChange(Username)(" ")
setting all the values touched true and set one of the values space. I also change the required massage to be equal to min massage so that the user cant understand this.
works for me... but I'm not sure if this solve is correct
props.setFieldValue('name', 'John Doe').then(() => { props.setFieldTouched('name', true, true) })
other hand (I used this one):
(async () => {
await props.setFieldValue('name', 'John Doe')
await props.setFieldTouched('name', true, true)
})()
works for me... but I'm not sure if this solve is correct
props.setFieldValue('name', 'John Doe').then(() => { props.setFieldTouched('name', true, true) })
other hand (I used this one):
(async () => { await props.setFieldValue('name', 'John Doe') await props.setFieldTouched('name', true, true) })()
The "await" for the setFieldValue may be redundant as it uses a separate dispatch. The promise is related to validation if I'm not mistaken.
I recommend removing the additional validation:
(async () => {
props.setFieldValue('name', 'John Doe', false) // <-- this line changed
await props.setFieldTouched('name', true, true)
})()
This is the code of the function in Formik repository:
const setFieldValue = useEventCallback(
(field: string, value: any, shouldValidate?: boolean) => {
dispatch({
type: 'SET_FIELD_VALUE',
payload: {
field,
value,
},
}); // <-- value changes in dispatch
const willValidate =
shouldValidate === undefined ? validateOnChange : shouldValidate;
return willValidate
? validateFormWithHighPriority(setIn(state.values, field, value)) // <-- validation only promise (not related to value update)
: Promise.resolve();
}
);
WDT @iqwik ?