【React全家桶入门之四】加入表单验证

我们的现在可以在应用里添加用户了。但是还存在不小的问题:

  • 用户可以输入任意长的名字
  • 用户可以输入任意的年龄
  • 用户可以不选择性别

盲目信任用户输入的数据,会给系统埋下不小的隐患。这回我们就来把这隐患扼杀在摇篮之中。

表单验证无非就是对用户输入的数据进行有效性、非空性验证,验证失败会在相应的地方显示错误信息,并阻止用户提交表单。

我们需要记录每一个字段当前的有效状态,有效时隐藏错误信息,无效时显示错误信息

而这个有效/无效,可以在表单值改变的时候进行判断。

我们对/src/pages/UserAdd.js进行修改:

首先修改了state的结构,把每个表单的值都放到了一个form字段中,方便统一管理;然后每个表单的值都变为了一个包含valid和value还有error字段的对象,valid表示该值的有效状态,value表示该表单具体的值,error表示错误提示信息:

  ...
  constructor () {
    super();
    this.state = {
      form: {
        name: {
          valid: false,
          value: '',
          error: ''
        },
        age: {
          valid: false,
          value: 0,
          error: ''
        },
        gender: {
          valid: false,
          value: '',
          error: ''
        }
      }
    };
  }
  ...
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

handleValueChange方法中,根据参数field获取state中对应表单的对象,然后根据新的值value判断新的值是否有效,将新的值和新的有效状态更新到state里。

  ...
  handleValueChange (field, value, type = 'string') {
    if (type === 'number') {
      value = +value;
    }

    const {form} = this.state;

    const newFieldObj = {value, valid: true, error: ''};

    switch (field) {
      case 'name': {
        if (value.length >= 5) {
          newFieldObj.error = '用户名最多4个字符';
          newFieldObj.valid = false;
        } else if (value.length === 0) {
          newFieldObj.error = '请输入用户名';
          newFieldObj.valid = false;
        }
        break;
      }
      case 'age': {
        if (value > 100 || value <= 0) {
          newFieldObj.error = '请输入1~100之间的数字';
          newFieldObj.valid = false;
        }
        break;
      }
      case 'gender': {
        if (!value) {
          newFieldObj.error = '请选择性别';
          newFieldObj.valid = false;
        }
        break;
      }
    }

    this.setState({
      form: {
        ...form,
        [field]: newFieldObj
      }
    });
  }
  ...
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

handleSubmit方法中对每个字段的valid进行检测,如果有一个valid为false则直接return以中断提交操作。

  ...
  handleSubmit (e) {
    e.preventDefault();

    const {form: {name, age, gender}} = this.state;
    if (!name.valid || !age.valid || !gender.valid) {
      alert('请填写正确的信息后重试');
      return;
    }

    fetch('http://localhost:3000/user', {
      method: 'post',
      body: JSON.stringify({
        name: name.value,
        age: age.value,
        gender: gender.value
      }),
      headers: {
        'Content-Type': 'application/json'
      }
    })
      .then((res) => res.json())
      .then((res) => {
        if (res.id) {
          alert('添加用户成功');
        } else {
          alert('添加失败');
        }
      })
      .catch((err) => console.error(err));
  }
  ...
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

最后,也要对render方法进行更新:

  render () {
    const {form: {name, age, gender}} = this.state;
    return (
      <div>
        <header>
          <h1>添加用户</h1>
        </header>

        <main>
          <form onSubmit={(e) => this.handleSubmit(e)}>
            <label>用户名:</label>
            <input
              type="text"
              value={name.value}
              onChange={(e) => this.handleValueChange('name', e.target.value)}
            />
            {!name.valid && <span>{name.error}</span>}
            <br/>
            <label>年龄:</label>
            <input
              type="number"
              value={age.value || ''}
              onChange={(e) => this.handleValueChange('age', e.target.value, 'number')}
            />
            {!age.valid && <span>{age.error}</span>}
            <br/>
            <label>性别:</label>
            <select
              value={gender.value}
              onChange={(e) => this.handleValueChange('gender', e.target.value)}
            >
              <option value="">请选择</option>
              <option value="male"></option>
              <option value="female"></option>
            </select>
            {!gender.valid && <span>{gender.error}</span>}
            <br/>
            <br/>
            <input type="submit" value="提交"/>
          </form>
        </main>
      </div>
    );
  }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

来看一下最终效果: 

基本的表单验证就完成了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值