我们的现在可以在应用里添加用户了。但是还存在不小的问题:
- 用户可以输入任意长的名字
- 用户可以输入任意的年龄
- 用户可以不选择性别
盲目信任用户输入的数据,会给系统埋下不小的隐患。这回我们就来把这隐患扼杀在摇篮之中。
表单验证无非就是对用户输入的数据进行有效性、非空性验证,验证失败会在相应的地方显示错误信息,并阻止用户提交表单。
我们需要记录每一个字段当前的有效状态,有效时隐藏错误信息,无效时显示错误信息。
而这个有效/无效,可以在表单值改变的时候进行判断。
我们对/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
来看一下最终效果:
基本的表单验证就完成了!