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

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

我们对/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;

.

react 项目实战(三)表单验证的更多相关文章

  1. jQuery框架学习第十一天:实战jQuery表单验证及jQuery自动完成提示插件

    jQuery框架学习第一天:开始认识jQueryjQuery框架学习第二天:jQuery中万能的选择器jQuery框架学习第三天:如何管理jQuery包装集 jQuery框架学习第四天:使用jQuer ...

  2. 最适合入门的Laravel中级教程(三)表单验证

    做开发有个原则是永远不能信任用户输入的数据: 即便前端已经做了验证: 在后端 php 也必须要再次验证: laravel 为表单验证提供了强大且简单的方案: 创建示例路由: routes/web.ph ...

  3. SPA项目之CRUD+表单验证

    1. 表单验证 Form组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则, 并将Form-Item的prop属性设置为需校验的字段名即可 <el-dialog :titl ...

  4. vue表单验证:vee-validate中文提示

    官方文档:https://baianat.github.io/vee-validate/guide/ vee-validate可用于vue项目中进行表单验证,使用方法在官方API上都可以查到: 使用过 ...

  5. Vue如何使用vee-validate表单验证

    Vue项目遇到要表单验证了吧,对我来说表单验证是个很纠(dan)结(teng)的内容,各种判断凌乱到飞起.往常使用jquery的validate插件做表单验证方便吧,你也可以在Vue里引入jquery ...

  6. react 项目实战(四)组件化表单/表单控件 高阶组件

    高阶组件:formProvider 高阶组件就是返回组件的组件(函数) 为什么要通过一个组件去返回另一个组件? 使用高阶组件可以在不修改原组件代码的情况下,修改原组件的行为或增强功能. 我们现在已经有 ...

  7. 群里分享的react的收藏一下!今日周末,改了个表单验证然后无所事事了!

    今日周末,改了个表单验证然后无所事事了,然后把昨天群里分享的react的收藏一下尽管现在还在研究angular和nodeJs毕竟刚刚开始用有点不熟...没准以后会研究一下react毕竟看着下面这张图还 ...

  8. 关于Web项目里的给表单验证控件添加结束时间不得小于开始时间的验证方法,日期转换和前台显示格式之间,还有JSON取日期数据格式转换成标准日期格式的问题

    项目里有些不同页面间的日期显示格式是不同的, 第一个问题: 比如我用日期控件WdatePicker.js导包后只需在input标签里加上onClick="WdatePicker()" ...

  9. JaveWeb 公司项目(4)----- Easyui的表单验证

    前面三篇博文讲述的是界面的搭建和数据的传输,可以看出目前我做的这个小项目已经有了一个大体的雏形,剩下的就是细节部分的打磨和一些友好的人机交互设计,今天做的是表单的验证,作为初学者,着实花了一番功夫,所 ...

  10. 如何在Vue的项目里对element的表单验证进行封装

    介绍需求 熟悉并优化公司项目的第五天,领导说能不能把表单验证封装一下,我打开代码一看 由于是后台管理系统,无数个需要验证的输入框,由于截图长度受限,只能展示部分,类似于这种页面还有无数个!代码重复率非 ...

随机推荐

  1. Python之三元运算、集合、函数

    一.三元运算符 三元运算符就是在赋值变量的时候,可以直接加判断,然后赋值 格式:[on_true] if [expression] else [on_false] res = 值1 if 条件 els ...

  2. shell脚本的练习

    创建一个以.sh结束的文件. 规则: 文件的头部使用#!/bin/sh 开头   这个是一个标识的作用,告诉使用哪种脚本来执行 echo 用来向命令行来输出的东西

  3. 常用的HTTP方法有哪些?

    GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器POST:用于传输数据给服务器,主要功能与GET方法类似,但一般推荐使用POST方式.PUT: 传输数据,报文 ...

  4. 06C#类

    C#类 1.2      类的继承 在1.3节,定义了一个描述个人情况的类Person,如果我们需要定义一个雇员类,当然可以从头开始定义雇员类Employee.但这样不能利用Person类中已定义的函 ...

  5. vue-cli webpack 快速搭建项目

    一.安装vue npm install vue -g 二.用vue-cli快速搭建项目 //全局安装vue-cli npm install install -g vue-cli //创建一个基于web ...

  6. Html、Css、JavaScript 遇到的问题总结

    $('body').scrollTop()无效得解决方案 鼠标滑轮获取到得值为0:var scrollTop = $('body').scrollTop(); 在页面中加一个随着页面滚动条滚动的小图片 ...

  7. C++ string 转整数

    使用 sstream 完成转换, #include <iostream> #include <string> #include <sstream> #include ...

  8. ALLEGRO中新画的热风焊盘不能找到的解决办法

    新画的热风焊盘(PCB Thermal Relif)改了路径,要想在Pad Designer中找到,方法是在allegro中Setup-User Preference Editor-Paths-Lib ...

  9. Android OkHttp(1)

     Android OkHttp(1) OkHttp是一个流行的第三方开源网络请求框架,在目前的一些APP开发中比较流行.Android平台开源的网络请求框架不少,比如常见的Volley, Asyn ...

  10. Linux读取网卡流量脚本

    #!/bin/bash #eval `date "+day=%d; month=%m; year=%Y; hour=%H; minute=%M second=%S"` #INSTF ...