setFieldError is overwritten when using the validation methods.
See original GitHub issueI’ve been beating my head against the wall on this one. I dug into the formik source and finally figured out what was going on. I’m writing to document what I found. Hopefully it’ll help someone else. This also might be a bug. If it is, then sweet. I found a bug.
Problem
The problem was in a custom component I was using the SetFieldValue and SetFieldError. Each of these methods take a field name. SetFieldValue’s second parameter is the value, SetFieldError’s second parameter is the error message.
setFieldValue('birth', value)
setFieldError('birth', value.error);
There are other elements on the form that are validated with yupjs.
I found when using setFieldError, you can’t use the validate or the validateSchema functions defined in the withFormik method configuration. Both the validate and the validateScheme overwrite the error collection.
/**
* Run validation against a Yup schema and optionally run a function if successful
*/
runValidationSchema = (values: FormikValues, onSuccess?: Function) => {
const { validationSchema } = this.props;
const schema = isFunction(validationSchema)
? validationSchema()
: validationSchema;
validateYupSchema(values, schema).then(
() => {
this.setState({ errors: {} });
if (onSuccess) {
onSuccess();
}
},
(err: any) =>
this.setState({ errors: yupToFormErrors(err), isSubmitting: false })
);
};
It happens in the error function where the state is set: this.setState({ errors: yupToFormErrors(err), isSubmitting: false }) .
For example, if I created a custom control called ImpreciseDateControl and wanted to set an error onBlur like below:
<ImpreciseDateControl
onChange={value => setFieldValue('birth', value)}
onBlur={value => {
setFieldTouched('birth', true);
setFieldError('birth', value.error);
}
}
label="Birth"
value={values.birth || {}}
/>
Even though I set the setFieldError for the birth field, it will be wiped out by one of the validation methods.
A possible solution is to pass the error collection into the validate methods, but this would require a change to the Formik code. This way the consumer would have the option to preserve all or selected errors.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:20
- Comments:8 (2 by maintainers)
Top Related StackOverflow Question
You can tell setFieldValue not to run validation by passing third parameter as
false.You cannot use
handleChangeorhandleBlurto get this specific behavior. YOu need to manually handle both blur and change with setFieldValue and and setFieldTouched. You’ll need to also pass the third argument (i.e.shouldValidate) to each asfalse.