问题
我有一个 formik 表单,需要有 2 个不同的验证模式,具体取决于用户使用哪个按钮提交。我看到有些人说使用状态来决定哪个,但我想避免使用状态,因为在这种情况下感觉不对。
我已经查看了是的文档,看来您可以直接使用模式并传递值进行验证。这似乎是有效的,正如我在示例中所示的那样,但是它返回的验证错误是无用的,我需要将它们转换为能够使用 Formik setErrors 帮助器。
是的,根据文档进行验证
let validationErrors = null;
try {
// Validate the form data using a custom Schema
await createDraftContractorFormValidationSchema.validate(values, { abortEarly: false, strict: false });
}
catch (errors: any) {
console.log(errors);
// What I essentially need here is a way to transform these errors
// into an object with the keys being the field that has errors and the message
if (errors) {
formikRef.current.setErrors(errors);
}
}
记录什么内容
ValidationError: 4 errors occurred
at finishTestRun (runTests.js:54:1)
at runTests.js:8:1
at finishTestRun (runTests.js:54:1)
at runTests.js:8:1
at finishTestRun (runTests.js:54:1)
at createValidation.js:60:1
我最终所做的事情是在一些不起眼的论坛中找到的,但我认为它将来可能对 Stack 上的其他人有用。感谢回答https://lightrun.com/answers/jaredpalmer-formik-yup-schemavalidate-options-show-every-error-of-a-field-at-the-same-time。
本质上,我创建了一个辅助方法,将 Yup 的验证错误转换为一个有用的对象,您可以将其直接传递到 Formik 的 setErrors 方法中。
帮手
/**
* TransformYupErrorsIntoObject
*
* @description Transform the useless yup error into a useable validation object
* @param {ValidationError} errors Yup validation errors
* @returns {Record<string, string>} Validation errors
*/
export const transformYupErrorsIntoObject = (errors: ValidationError): Record<string, string> => {
const validationErrors: Record<string, string> = {};
errors.inner.forEach((error: any) => {
if (error.path !== undefined) {
validationErrors[error.path] = error.errors[0];
}
});
return validationErrors;
};
实施
try {
// You need to define this schema as a model of your form
// Abort early will ensure all the fields validate not just one
await createDraftContractorFormValidationSchema.validate(values, { abortEarly: false, strict: false });
}
catch (error: any) {
// Transform the validationErrors
const validationErrors = transformYupErrorsIntoObject(error);
// Set errors on the field showing the user the errors
formikRef.current.setErrors(validationErrors);
return;
}
将 Yup 错误(字符串数组)转换为 JavaScript 对象(键:值对)的 JavaScript 版本。 基于 Vuk 的贡献--@Vuk
/**
* TransformYupErrorsIntoObject
*
* @description Transform the useless yup error into a useable validation object
* @param {ValidationError} errors Yup validation errors
* @returns {Record<string, string>} Validation errors
*/
export const YupErrorsIntoObject = (errors) => {
const validationErrors = {};
errors.inner.forEach((error) => {
if (error.path !== undefined) {
validationErrors[error.path] = error.errors[0];
}
});
return validationErrors;
};
const [practiceData, setPracticeData] = useState({
firstName: '',
lastName: '',
role: '',
email: '',
phoneNumber: '',
})
const [Error, setError] = useState({ isErr: false, message: '' })
const handleSubmit = (e) => {
e.preventDefault()
schema
.validate(practiceData, { abortEarly: false })
.then((val) => console.log(val))
//I've got all the errors just by writing err.errors in message.
.catch((err) => setError({ isErr: true, message: err.errors }))
}
//Output
['First Name is required!', 'Last Name is required!', 'Role is required!', 'Email is required!', 'phoneNumber must be a `number` type, but the final value was: `NaN` (cast from the value `""`).']