表單是前端開發(fā)中必不可少的組件拗踢,React作為前端框架会钝,如果不能處理表單,就會被億萬的前端工程師吐槽的火俄。然而React對于表單的處理犯建,還是有一些細(xì)節(jié)上的東西需要關(guān)注,接下來我們詳細(xì)的描述在React中如何使用表單組件。
為了讓頁面效果美觀一點瓜客,在頁面中引入bootstrap
的css
npm install bootstrap --save
在react組件中引入外部css文件适瓦,直接可以使用import
import 'bootstrap/dist/css/bootstrap.css'
我們操作使用react,開發(fā)中最多的內(nèi)容就是操作state中的數(shù)據(jù),那么進(jìn)行表單開發(fā)谱仪,就是要將表單中的數(shù)據(jù)與state中的數(shù)據(jù)關(guān)聯(lián)起來玻熙,也就是說,當(dāng)用戶改變表單中的數(shù)據(jù)時疯攒,state中的數(shù)據(jù)也會相應(yīng)的發(fā)生修改嗦随,當(dāng)state中的數(shù)據(jù)發(fā)生了修改,form中的數(shù)據(jù)也會進(jìn)行相應(yīng)的變化敬尺。這種變化枚尼,以Angularjs
的雙向綁定最為著名,然而砂吞,react并沒有使用雙向綁定姑原,而是使用了單向數(shù)據(jù)流。
單向數(shù)據(jù)流
在這里描述單向數(shù)據(jù)流呜舒,并不采用一些比較正規(guī)的說法锭汛,我所說的是在開發(fā)中的直觀感受。在前端開發(fā)過程中袭蝗,數(shù)據(jù)最終展示在頁面中唤殴,需要經(jīng)過一個渲染過程,即改變?yōu)g覽器頁面中的DOM結(jié)構(gòu)或者DOM中的內(nèi)容,從而瀏覽器進(jìn)行了解析渲染哪轿,如果要開發(fā)人員手動寫原生的JS代碼操作DOM稚虎,在開發(fā)復(fù)雜應(yīng)用時,那將是一個極其痛苦的過程配名。單向數(shù)據(jù)流的作用就是,當(dāng)內(nèi)存中的數(shù)據(jù)發(fā)生變化時晋辆,在頁面的相應(yīng)位置上渠脉,會自動的渲染這些數(shù)據(jù),這就意味著開發(fā)人員不再寫DOM操作的代碼瓶佳。
所謂單向數(shù)據(jù)流芋膘,意味著數(shù)據(jù)從一個地方流向另一個地方,即從瀏覽器內(nèi)存 到 頁面DOM樹
這就是react的強(qiáng)大之處,同時也是其短板之處为朋,從內(nèi)存到DOM臂拓,可以自動渲染,但是從DOM到內(nèi)存习寸,就需要開發(fā)人員手動處理胶惰。
創(chuàng)建表單
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;
此時的表單中,其內(nèi)部數(shù)據(jù)的狀態(tài)由其自身維持霞溪,當(dāng)用戶在表單中進(jìn)行輸入時童番,表單的數(shù)據(jù)狀態(tài)發(fā)生了變化,但是state中的狀態(tài)仍然保持原狀態(tài)威鹿,React只對表單組件進(jìn)行了渲染剃斧,但并未控制其后續(xù)輸入的變化,我們稱此時的表單組件為非受控組件忽你。
讓React渲染表單組件幼东,組件中的值由React賦予,并控制其因用戶輸入所帶來的變化科雳,即讓表單組件成為受控組件
- 表單組件的value值由React進(jìn)行初始化
<input type="text" className="form-control" id="name" value={this.state.name} name="name" placeholder="用戶名" onChange={this.handleChange}/>
- 監(jiān)聽組件change事件根蟹,將其變化的值修改保存到state中
handleChange = (event) =>{
this.setState({
[event.target.name]:event.target.value
});
}
對于text
,textarea
,上述的方式均可糟秘,radio
由于是單選简逮,所以仍舊可以按照text的方式進(jìn)行處理,但是對于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"/>美術(shù)
</label>
</div>
<div className="checkbox">
<label>
<input type="checkbox" name="hobby" value="3"/>體操
</label>
</div>
</div>
</div>
checkbox
組件為多選散庶,所以,state中就需要使用數(shù)組來存儲數(shù)據(jù)
- 使用onChange事件控制組件
- 修改state屬性凌净,要根據(jù)組件的
checked
屬性來判斷
3.設(shè)置組件中的checked
的值悲龟,需要根據(jù)state中的數(shù)據(jù)進(jìn)行判斷
- 初始化state
constructor(props){
super(props);
this.state = {
music:false,
draw:false,
gymnastics:false
};
}
- 為組件綁定
onChange
并對其checked
進(jìn)行判斷
<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}/>美術(shù)
</label>
</div>
<div className="checkbox">
<label>
<input type="checkbox" name="gymnastics" checked={this.state.gymnastics} onChange={this.handleChange}/>體操
</label>
</div>
</div>
</div>
- 在onChange函數(shù)中進(jìn)行數(shù)據(jù)處理
handleChange = (event) =>{
var temp = {
[event.target.name]:event.target.checked
};
this.setState(temp);
}
列表
現(xiàn)在業(yè)內(nèi)流行的前端框架對于列表循環(huán)的支持,可以說是解放了廣大 前端開發(fā)人員冰寻,從前的jquery瘋狂拼接字符串须教,到后來使用一些插件,而現(xiàn)在斩芭,一切變得很簡單
1.定義一組數(shù)組
const users = [{
id:1,
name:'張三',
age:10
},{
id:2,
name:'李四',
age:10
},{
id:3,
name:'王五',
age:10
},{
id:4,
name:'趙六',
age:10
}];
2.在render函數(shù)中首先根據(jù)數(shù)組生成列表組件
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函數(shù)中返回的結(jié)構(gòu)中
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>
);
此時就得到一個完美的列表
返回值得結(jié)構(gòu)中的組件與前面使用map函數(shù)的遍歷結(jié)構(gòu)是等價的,因此划乖,我們可以直接JSX中使用map函數(shù)遍歷
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從零開始系 學(xué)習(xí)的系列就要結(jié)束了
之后我要重新回歸java的學(xué)習(xí)中了!