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

如何在React中编写正确的表单校验?现有异常问题求助

问题根因

  • 问题1(空提交优先触发手机号错误):你所有表单字段的初始state为undefined,正则校验时undefined会被隐式转为字符串"undefined",刚好符合公司、姓名的正则规则,校验直接通过到手机号环节才失败,所以只弹出手机号错误提示。同时你给输入框加了原生required属性,自定义校验和原生校验逻辑冲突也会导致提示顺序异常。
  • 问题2(未填公司可提交):你判断空值的逻辑是company === "",如果用户从未操作过公司输入框,company的值始终是初始的undefined,和空字符串判断不相等,空值校验直接跳过,同时"undefined"符合公司名称正则规则,所以校验通过允许提交。

另外你手机号正则加了全局g修饰符,多次调用test方法时会因为lastIndex偏移出现校验异常。

修复步骤

  1. 所有表单相关state初始化时设置默认值为空字符串,避免undefined隐式转换问题:
// 修正前
const [company, setCompany] = useState();
// 修正后
const [company, setCompany] = useState('');
// 姓名、手机号、邮箱的state都按此规则修改初始值
  1. 去掉所有input标签上的required属性,用你自定义的校验逻辑即可,避免和原生校验冲突。
  2. 移除手机号正则的全局g修饰符:
// 修正前
const rePhone = /\+?[0-9]+([0-9]|\/|\(|\)|\-| ){10,}/g;
// 修正后
const rePhone = /\+?[0-9]+([0-9]|\/|\(|\)|\-| ){10,}/;
  1. 调整onClick校验逻辑,先做非空判断,所有字段校验全部执行完成后再判断是否允许提交,不要中途return:
const onClick = (e) => {
  const reCompanyName = /^[a-zA-Z](?:[^0-9\s\x00-\x1F]|[ \t]){1,79}$/;
  const reName = /[A-Za-z]{1,50}/;
  const reEmail = /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/;
  const rePhone = /\+?[0-9]+([0-9]|\/|\(|\)|\-| ){10,}/;

  let hasError = false;
  // 公司校验
  if (!company.trim()) {
    setCompanyValidate(true);
    hasError = true;
  } else if (!reCompanyName.test(company)) {
    setCompanyValidate(true);
    hasError = true;
  } else {
    setCompanyValidate(false);
  }
  // 姓名校验
  if (!name.trim()) {
    setNameValidate(true);
    hasError = true;
  } else if (!reName.test(name)) {
    setNameValidate(true);
    hasError = true;
  } else {
    setNameValidate(false);
  }
  // 手机号校验
  if (!phone.trim()) {
    setPhoneValidation(true);
    hasError = true;
  } else if (!rePhone.test(phone)) {
    setPhoneValidation(true);
    hasError = true;
  } else {
    setPhoneValidation(false);
  }
  // 邮箱校验
  if (!email.trim()) {
    setEmailValidate(true);
    hasError = true;
  } else if (!reEmail.test(email)) {
    setEmailValidate(true);
    hasError = true;
  } else {
    setEmailValidate(false);
  }

  // 有错误直接终止提交
  if (hasError) return;

  // 原有提交逻辑
  setCompanyValue(company);
  setNameValue(name);
  setPhoneValue(phone);
  setEmailValue(email);
  setCompany("");
  setName("");
  setPhone("");
  setEmail("");
  setInput(false);
  setMessage(false);
  setSubMessage(false);
  setLine(true);
  setBtn(false);
  setTimeout(() => {
    setInput(true);
    setMessage(true);
    setSubMessage(true);
    setLine(false);
    setBtn(true);
    setCompanyValidate(false);
    setNameValidate(false);
    setPhoneValidation(false);
    setEmailValidate(false);
  }, 5000);
};

内容的提问来源于stack exchange,提问作者Spactex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:06:07