React TSX页面中获取Yup.test()错误提示信息的方法
解决Yup自定义验证错误提示获取问题
首先,你需要给自定义的test规则添加上错误提示信息和唯一测试名称,让Yup能把错误关联到对应字段:
Yup.object().shape({ names: Yup.array().of( Yup.object().shape({ firstName: Yup.string() .required('First Name is required.') .max(45, 'Only 45 characters allowed.'), middleName: Yup.string(), lastName: Yup.string() .required('Last Name is required.') .max(45, 'Only 45 characters allowed.'), }).test({ name: 'totalNameLength', // 给测试规则命名,方便定位错误 message: 'Total length of first, middle, and last name cannot exceed 75 characters.', // 自定义错误提示 test: ({ firstName, middleName, lastName }) => { return (firstName?.length ?? 0) + (middleName?.length ?? 0) + (lastName?.length ?? 0) <= 75; }, }) ) })
基于Formik的错误获取与展示(React常用表单方案)
Formik会自动把Yup验证错误存入errors对象,数组字段的错误会按索引嵌套:
- 第一个联系人的总长度错误路径:
errors.names?.[0]?.totalNameLength - 错误触发状态(用户是否触碰过字段组):
touched.names?.[0]?.totalNameLength
在TSX中渲染表单时,可这样展示错误:
{formik.values.names?.map((name, index) => ( <div key={index} className="name-group"> <input name={`names[${index}].firstName`} value={name.firstName || ''} onChange={formik.handleChange} onBlur={formik.handleBlur} /> <input name={`names[${index}].middleName`} value={name.middleName || ''} onChange={formik.handleChange} onBlur={formik.handleBlur} /> <input name={`names[${index}].lastName`} value={name.lastName || ''} onChange={formik.handleChange} onBlur={formik.handleBlur} /> {/* 展示总长度错误 */} {formik.touched.names?.[index] && formik.errors.names?.[index]?.totalNameLength && ( <span className="error-text"> {formik.errors.names[index].totalNameLength} </span> )} </div> ))}
原生React状态管理的错误处理
如果不用Formik,可手动调用Yup的validate方法获取错误:
const schema = Yup.object().shape({ /* 你的验证规则 */ }); const validateForm = async (values: ClientContact) => { try { await schema.validate(values, { abortEarly: false }); // 关闭提前终止,获取所有错误 return {}; } catch (err: any) { return err.inner.reduce((acc: Record<string, string>, curr: any) => { acc[curr.path] = curr.message; return acc; }, {}); } }; // 组件内使用 const [formValues, setFormValues] = useState<ClientContact>({ names: [{ firstName: '', lastName: '' }] }); const [errors, setErrors] = useState<Record<string, string>>({}); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const validationErrors = await validateForm(formValues); if (Object.keys(validationErrors).length === 0) { // 提交逻辑 } else { setErrors(validationErrors); } };
然后在TSX中根据错误路径展示提示:
{errors[`names[${index}].totalNameLength`] && ( <span className="error-text"> {errors[`names[${index}].totalNameLength`]} </span> )}
内容的提问来源于stack exchange,提问作者rexroxm
相关产品推荐
相关产品推荐

