You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:30:50