zoukankan      html  css  js  c++  java
  • 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: ''
          }
        }
      };
    }
    ...

    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 || !value) {
            newFieldObj.error = '请输入1~100之间的数字';
            newFieldObj.valid = false;
          }
          break;
        }
        case 'gender': {
          if (!value) {
            newFieldObj.error = '请选择性别';
            newFieldObj.valid = false;
          }
          break;
        }
        default: {
          //
        }
      }
    
      this.setState({
        form: {
          ...form,
          [field]: newFieldObj
        }
      });
    }
    ...

    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));
    }
    ...

    最后,也要对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>
      );
    }

    来看一下最终效果: 

    注:完整代码 src / pages / UserAdd.js

    import React from 'react';
    
    // 添加用户组件
    class UserAdd extends React.Component {
      // 构造器
      constructor(props) {
        super(props);
        // 定义初始化状态
        this.state = {
          form: {
            name: {
              valid: false, // 有效状态
              value: '', // 表单具体的值
              error: '' // 错误提示信息
            },
            age: {
              valid: false,
              value: '',
              error: ''
            },
            gender: {
              valid: false,
              value: '',
              error: ''
            }
          }
        };
      }
      // 输入框改变事件
      handleValueChange(field, value, type='string') {
        // 由于表单的值都是字符串,我们可以根据传入type为number来手动转换value的类型为number类型
        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 || !value){
              newFieldObj.error = '请输入1~100之间的数字';
              newFieldObj.valid = false;
            }
            break;
          }
          case 'gender': {
            if(!value){
              newFieldObj.error = '请选择性别';
              newFieldObj.valid = false;
            }
            break;
          }
          default: {
            //
          }
        }
    
        // 设置状态
        this.setState({
          form: {
            ...form,
            [field]: newFieldObj
          }
        });
      }
      // 按钮提交事件
      handleSubmit(e){
        // 阻止表单submit事件自动跳转页面的动作
        e.preventDefault();
        // 定义常量
        const { form: { name, age, gender }} = this.state;
        // 验证
        if(!name.valid || !age.valid || !gender.valid){
          alert('请填写正确的信息后重试');
          return;
        }
        // 发送请求
        fetch('http://localhost:8000/user', {
          method: 'post',
          // 使用fetch提交的json数据需要使用JSON.stringify转换为字符串
          body: JSON.stringify({
            name: name.value,
            age: age.value,
            gender: gender.value
          }),
          headers: {
            'Content-Type': 'application/json'
          }
        })
        // 强制回调的数据格式为json
        .then((res) => res.json())
        // 成功的回调
        .then((res) => {
          // 当添加成功时,返回的json对象中应包含一个有效的id字段
          // 所以可以使用res.id来判断添加是否成功
          if(res.id){
            alert('添加用户成功!');
          }else{
            alert('添加用户失败!');
          }
        })
        // 失败的回调
        .catch((err) => console.error(err));
      }
      
      render() {
        // 定义常量
        const {form: {name, age, gender}} = this.state;
        return (
          <div>
            <header>
              <div>添加用户</div>
            </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>
        );
      }
    }
    
    export default UserAdd;
    

    .

  • 相关阅读:
    JS魔法堂:阻止元素被选中
    JS魔法堂之实战:纯前端的图片预览
    CentOS6.5菜鸟之旅:纯转载Linux目录结构
    Vim杂记:Sublime的配色方案
    Vim杂记:markdown插件
    CentOS6.5菜鸟之旅:中文编辑器忍痛放弃Sublime
    JS魔法堂:Data URI Scheme介绍
    CentOS6.5菜鸟之旅:安装ATI显卡驱动
    JS魔法堂:获取当前脚本文件的绝对路径
    腊八蒜
  • 原文地址:https://www.cnblogs.com/crazycode2/p/8462248.html
Copyright © 2011-2022 走看看