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

React类组件表单如何在提交前显示空字段错误及校验邮箱有效性

React类组件表单实时校验实现方案

1. 扩展state存储校验状态

首先在constructor的state中新增两个字段,用于记录用户交互状态和错误信息:

this.state = {
  // 原有state保持不变
  // ...
  // 新增校验相关状态
  touched: {
    entreprise: false,
    nom: false,
    prenom: false,
    email: false,
    telephone: false
  },
  errors: {
    entreprise: "",
    nom: "",
    prenom: "",
    email: "",
    telephone: ""
  }
};

2. 新增通用校验方法

抽离校验逻辑,可在输入、失焦、提交三个场景复用:

// 校验单个字段
validateField = (name, value) => {
  let error = "";
  const requiredFields = ["entreprise", "nom", "prenom", "email", "telephone"];
  // 必填校验
  if (requiredFields.includes(name) && value.trim() === "") {
    error = "该字段不能为空";
  }
  // 邮箱格式校验
  if (name === "email" && value.trim() !== "") {
    const emailReg = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailReg.test(value)) {
      error = "请输入有效的邮箱地址";
    }
  }
  return error;
};

// 校验全量表单
validateAll = () => {
  const errors = {};
  const requiredFields = ["entreprise", "nom", "prenom", "email", "telephone"];
  requiredFields.forEach(field => {
    errors[field] = this.validateField(field, this.state[field]);
  });
  this.setState({ errors });
  // 返回校验是否通过
  return Object.values(errors).every(error => error === "");
};

3. 改造事件处理函数

新增失焦事件处理,修改原有输入事件处理,实时触发校验:

// 新增失焦事件
handleBlur = (e) => {
  const { name } = e.target;
  this.setState(prev => ({
    touched: { ...prev.touched, [name]: true }
  }), () => {
    const error = this.validateField(name, this.state[name]);
    this.setState(prev => ({
      errors: { ...prev.errors, [name]: error }
    }));
  });
};

// 改造原有输入事件
handleChangeForm(event) {
  const { name, value } = event.target;
  this.setState({
    [name]: value
  }, () => {
    // 已触碰的字段实时校验
    if (this.state.touched[name]) {
      const error = this.validateField(name, value);
      this.setState(prev => ({
        errors: { ...prev.errors, [name]: error }
      }));
    }
  });
}

记得在constructor里绑定新增的handleBlur:

this.handleBlur = this.handleBlur.bind(this);

4. 给表单字段绑定错误属性

给所有必填TextField添加onBlur、error、helperText属性,Material UI会自动渲染错误样式和提示:

<TextField 
  id="entreprise"
  name="entreprise" 
  label="Nom entreprise"
  value={this.state.entreprise}
  onChange={this.handleChangeForm}
  onBlur={this.handleBlur}
  error={this.state.touched.entreprise && !!this.state.errors.entreprise}
  helperText={this.state.touched.entreprise && this.state.errors.entreprise}
  variant="outlined" margin="normal" fullWidth size="small" required/>

{/* 其他必填字段按照上面的格式统一修改,邮箱字段不需要额外改动,校验逻辑已经适配 */}
<TextField 
  id="email" 
  name="email" 
  type="email" 
  label="Votre adresse email" 
  value={this.state.email}
  onChange={this.handleChangeForm}
  onBlur={this.handleBlur}
  error={this.state.touched.email && !!this.state.errors.email}
  helperText={this.state.touched.email && this.state.errors.email}
  variant="outlined" margin="normal" fullWidth size="small" required/>

5. 提交逻辑增加前置校验

修改upload提交方法,提交前先做全量校验,校验通过再执行后续上传逻辑:

upload = () => {
  // 先标记所有必填字段为已触碰,展示所有错误
  const allTouched = Object.fromEntries(
    Object.keys(this.state.touched).map(key => [key, true])
  );
  this.setState({ touched: allTouched }, () => {
    const isFormValid = this.validateAll();
    if (!isFormValid) return; // 校验不通过直接终止
    
    // 原有上传逻辑写在这里
    // ...
  });
}

同时可以修改提交按钮的禁用逻辑,校验不通过时不可点击:

<Button
  className="btn-upload"
  color="primary"
  variant="contained"
  component="span"
  disabled={!this.state.selectedFiles && !this.state.hiddenUpload || Object.values(this.state.errors).some(err => err)}
  onClick={this.upload}>
  Envoyer
</Button>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:57:03