表单是前端开发中必不可少的组件,React作为前端框架,如果不能处理表单,就会被亿万的前端工程师吐槽的。然而React对于表单的处理,还是有一些细节上的东西需要关注,接下来我们详细的描述在React中如何使用表单组件。
为了让页面效果美观一点,在页面中引入bootstrap
的css
npm install bootstrap --save
在react组件中引入外部css文件,直接可以使用import
import 'bootstrap/dist/css/bootstrap.css'
我们操作使用react,开发中最多的内容就是操作state中的数据,那么进行表单开发,就是要将表单中的数据与state中的数据关联起来,也就是说,当用户改变表单中的数据时,state中的数据也会相应的发生修改,当state中的数据发生了修改,form中的数据也会进行相应的变化。这种变化,以Angularjs
的双向绑定最为著名,然而,react并没有使用双向绑定,而是使用了单向数据流。
单向数据流
在这里描述单向数据流,并不采用一些比较正规的说法,我所说的是在开发中的直观感受。在前端开发过程中,数据最终展示在页面中,需要经过一个渲染过程,即改变浏览器页面中的DOM结构或者DOM中的内容,从而浏览器进行了解析渲染,如果要开发人员手动写原生的JS代码操作DOM,在开发复杂应用时,那将是一个极其痛苦的过程。单向数据流的作用就是,当内存中的数据发生变化时,在页面的相应位置上,会自动的渲染这些数据,这就意味着开发人员不再写DOM操作的代码。
所谓单向数据流,意味着数据从一个地方流向另一个地方,即从浏览器内存 到 页面DOM树
这就是react的强大之处,同时也是其短板之处,从内存到DOM,可以自动渲染,但是从DOM到内存,就需要开发人员手动处理。
创建表单
import React from 'react';
import 'bootstrap/dist/css/bootstrap.css'
class App extends React.Component{
constructor(props){
super(props);
this.state = {
name:''
};
}
render(){
return (
<div className="container" style={{marginTop:'20px'}}>
<div className="row">
<div className="col-md-5">
<form className="form-horizontal">
<div className="form-group">
<label className="col-sm-2 control-label">用户名</label>
<div className="col-sm-10">
<input type="email" className="form-control" id="name" name="name" placeholder="用户名" />
</div>
</div>
</form>
</div>
</div>
</div>
);
}
}
export default App;
此时的表单中,其内部数据的状态由其自身维持,当用户在表单中进行输入时,表单的数据状态发生了变化,但是state中的状态仍然保持原状态,React只对表单组件进行了渲染,但并未控制其后续输入的变化,我们称此时的表单组件为非受控组件。
让React渲染表单组件,组件中的值由React赋予,并控制其因用户输入所带来的变化,即让表单组件成为受控组件
- 表单组件的value值由React进行初始化
<input type="text" className="form-control" id="name" value={this.state.name} name="name" placeholder="用户名" onChange={this.handleChange}/>
- 监听组件change事件,将其变化的值修改保存到state中
handleChange = (event) =>{
this.setState({
[event.target.name]:event.target.value
});
}
对于text
,textarea
,上述的方式均可,radio
由于是单选,所以仍旧可以按照text的方式进行处理,但是对于checkbox
,就需要做特殊的处理了
<div className="form-group">
<label className="col-sm-2 control-label">爱好</label>
<div className="col-sm-10">
<div className="checkbox">
<label>
<input type="checkbox" name="hobby" value="1"/>音乐
</label>
</div>
<div className="checkbox">
<label>
<input type="checkbox" name="hobby" value="2"/>美术
</label>
</div>
<div className="checkbox">
<label>
<input type="checkbox" name="hobby" value="3"/>体操
</label>
</div>
</div>
</div>
checkbox
组件为多选,所以,state中就需要使用数组来存储数据
- 使用onChange事件控制组件
- 修改state属性,要根据组件的
checked
属性来判断
3.设置组件中的checked
的值,需要根据state中的数据进行判断
- 初始化state
constructor(props){
super(props);
this.state = {
music:false,
draw:false,
gymnastics:false
};
}
- 为组件绑定
onChange
并对其checked
进行判断
<div className="form-group">
<label className="col-sm-2 control-label">爱好</label>
<div className="col-sm-10">
<div className="checkbox">
<label>
<input type="checkbox" name="music" checked={this.state.music} onChange={this.handleChange}/>音乐
</label>
</div>
<div className="checkbox">
<label>
<input type="checkbox" name="draw" checked={this.state.draw} onChange={this.handleChange}/>美术
</label>
</div>
<div className="checkbox">
<label>
<input type="checkbox" name="gymnastics" checked={this.state.gymnastics} onChange={this.handleChange}/>体操
</label>
</div>
</div>
</div>
- 在onChange函数中进行数据处理
handleChange = (event) =>{
var temp = {
[event.target.name]:event.target.checked
};
this.setState(temp);
}
列表
现在业内流行的前端框架对于列表循环的支持,可以说是解放了广大 前端开发人员,从前的jquery疯狂拼接字符串,到后来使用一些插件,而现在,一切变得很简单
1.定义一组数组
const users = [{
id:1,
name:'张三',
age:10
},{
id:2,
name:'李四',
age:10
},{
id:3,
name:'王五',
age:10
},{
id:4,
name:'赵六',
age:10
}];
2.在render函数中首先根据数组生成列表组件
const tbodys = users.map((user)=>{
return (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.age}</td>
</tr>
)
});
tbodys
就是一个我们需要的列表组件,然后将其添加到render函数中返回的结构中
return (
<div className="container" style={{marginTop:'30px'}}>
<div className="row">
<div className="col-md-8 col-md-offset-2">
<table className="table table-bordered">
<thead>
<tr>
<th>id</th>
<th>名称</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{tbodys}
</tbody>
</table>
</div>
</div>
</div>
);
此时就得到一个完美的列表
返回值得结构中的组件与前面使用map函数的遍历结构是等价的,因此,我们可以直接JSX中使用map函数遍历
render() {
return (
<div className="container" style={{marginTop:'30px'}}>
<div className="row">
<div className="col-md-8 col-md-offset-2">
<table className="table table-bordered">
<thead>
<tr>
<th>id</th>
<th>名称</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{
users.map((user)=>{
return (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.age}</td>
</tr>
)
})
}
</tbody>
</table>
</div>
</div>
</div>
);
}
写到这里呢,React从零开始系 学习的系列就要结束了
之后我要重新回归java的学习中了!