
本文旨在解决在使用 Formik 和 Yup 进行 React 表单验证时,如何针对特定字段(例如密码)同时展示所有验证错误,而对其他字段(例如邮箱)按顺序展示错误的问题。通过自定义 Yup 验证规则,我们可以灵活控制错误信息的展示方式,提升用户体验。
在使用 Formik 和 Yup 构建 React 表单时,经常需要对用户输入进行验证。默认情况下,Yup 会按照验证规则的顺序,只返回第一个遇到的错误。但在某些场景下,我们可能希望对某个字段(比如密码)同时展示所有验证错误,以便用户更全面地了解需要修改的地方。
以下是如何实现这种效果的方法:
核心思路:自定义 Yup 验证规则
我们可以利用 Yup 的 test 方法,自定义验证逻辑。在自定义的验证函数中,我们可以手动检查所有验证条件,并将所有错误信息收集起来,然后一次性抛出。
实现步骤:
创建 Yup Schema:
首先,我们需要定义一个 Yup Schema,用于描述表单字段的验证规则。对于需要展示所有错误的字段(例如密码),使用 test 方法进行自定义验证。
import * as Yup from 'yup';import { useFormik } from 'formik';const validationSchema = Yup.object({ email: Yup.string().required("Required field").email("Invalid email format"), password: Yup.string() .required("Required field password") .test({ test: (value) => { let errors = []; if (!/^(?=.{8,})/.test(value)) { errors.push("Must Contain 8 Characters"); } if (!/^(?=.*[!@#$%^&*])/.test(value)) { errors.push("One Special Case Character"); } if (!/^(?=.*[0-9])/.test(value)) { errors.push("One Number"); } if (!/^(?=.*[a-z])/.test(value)) { errors.push("One Lowercase"); } if (!/^(?=.*[A-Z])/.test(value)) { errors.push("One Uppercase"); } if (errors.length > 0) { throw new Yup.ValidationError({ errors: errors, inner: true, path: "password", message: errors, value: value, name: "ValidationError", }); } return true; }, }),});
在这个例子中,password 字段的验证使用了 test 方法。在 test 函数中,我们依次检查密码是否满足长度、是否包含特殊字符、数字、大小写字母等条件。如果任何一个条件不满足,就将对应的错误信息添加到 errors 数组中。最后,如果 errors 数组不为空,就抛出一个 Yup.ValidationError 异常,其中包含了所有的错误信息。
使用 Formik:
接下来,我们需要使用 Formik 来管理表单状态和处理表单提交。
const formik = useFormik({ initialValues: { email: "", password: "", }, validationSchema: validationSchema, onSubmit: (values) => { alert(JSON.stringify(values)); },});const { errors, touched } = formik;
在这里,我们将上面定义的 validationSchema 传递给 Formik 的 validationSchema 属性。Formik 会自动使用 Yup 来验证表单数据,并将错误信息存储在 errors 对象中。
展示错误信息:
最后,我们需要在 UI 中展示错误信息。对于 password 字段,我们可以遍历 errors.password 数组,展示所有的错误信息。
{formik.touched.email && formik.errors.email ? ({formik.errors.email}) : null}{formik.touched.password && errors.password ? ({Array.isArray(errors.password) ? ( errors.password.map((error, index) => () : null}{error})) ) : ({errors.password})}
在这个例子中,我们首先判断 errors.password 是否存在,以及用户是否已经 touched 了该字段。如果两个条件都满足,我们就判断 errors.password 是否是一个数组。如果是数组,就遍历数组,展示所有的错误信息。如果不是数组,就直接展示错误信息。
完整示例:
import React from 'react';import { useFormik } from 'formik';import * as Yup from 'yup';const validationSchema = Yup.object({ email: Yup.string().required("Required field").email("Invalid email format"), password: Yup.string() .required("Required field password") .test({ test: (value) => { let errors = []; if (!/^(?=.{8,})/.test(value)) { errors.push("Must Contain 8 Characters"); } if (!/^(?=.*[!@#$%^&*])/.test(value)) { errors.push("One Special Case Character"); } if (!/^(?=.*[0-9])/.test(value)) { errors.push("One Number"); } if (!/^(?=.*[a-z])/.test(value)) { errors.push("One Lowercase"); } if (!/^(?=.*[A-Z])/.test(value)) { errors.push("One Uppercase"); } if (errors.length > 0) { throw new Yup.ValidationError({ errors: errors, inner: true, path: "password", message: errors, value: value, name: "ValidationError", }); } return true; }, }),});const MyForm = () => { const formik = useFormik({ initialValues: { email: "", password: "", }, validationSchema: validationSchema, onSubmit: (values) => { alert(JSON.stringify(values)); }, }); const { errors, touched } = formik; return ( {formik.touched.email && formik.errors.email ? ( {formik.errors.email} ) : null} {formik.touched.password && errors.password ? ( {Array.isArray(errors.password) ? ( errors.password.map((error, index) => ( {error} )) ) : ( {errors.password} )} ) : null} );};export default MyForm;
注意事项:
path 属性在 Yup.ValidationError 中非常重要,它告诉 Formik 哪个字段出现了错误。确保错误信息清晰易懂,方便用户修改。可以根据实际需求自定义验证规则和错误信息。
总结:
通过自定义 Yup 验证规则,我们可以灵活地控制表单验证的逻辑和错误信息的展示方式。这种方法可以帮助我们提升用户体验,让用户更轻松地填写表单。希望本文能够帮助你更好地使用 Formik 和 Yup 进行表单验证。
以上就是使用 Formik 和 Yup 实现 React 表单多重错误展示的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1526033.html
微信扫一扫
支付宝扫一扫