一详拙、綁定事件
1、綁定事件處理函數(shù)this獲取數(shù)據(jù)的幾種方法:
第一種方式:在事件上使用bind(this)
<button onClick={this.getData1.bind(this)}>獲取數(shù)據(jù)方法1</button>
第二種方式:在構(gòu)造函數(shù)中改變this指向
this.getData2=this.getData2.bind(this)
<button onClick={this.getData2}>獲取數(shù)據(jù)方法2</button>
第三種方式:使用=()=>
getData3=()=>{
alert(this.state.dataMsg)
}
<button onClick={this.getData3}>獲取數(shù)據(jù)方法3</button>
關(guān)于React中this指向問題
JavaScript函數(shù)中的this不是在函數(shù)聲明的時(shí)候定義的,而是在函數(shù)調(diào)用(即運(yùn)行)的時(shí)候定義的镀虐。在react中也遵循這個(gè)原則模暗,this指向該function的調(diào)用方,所以“調(diào)用者”不同會(huì)導(dǎo)致this的不同弃揽,這里的“調(diào)用者”指的是函數(shù)執(zhí)行時(shí)的當(dāng)前對象。
箭頭函數(shù)或是bind會(huì)改變this的指向则北。上面的this.state矿微,之所以能夠訪問到state就是改變了this的指向,不然getData里的this就是指向這個(gè)function尚揣,這是的this是undefined涌矢。
一般來說:
????1、誰調(diào)用的this就指向誰快骗。
????2娜庇、箭頭函數(shù),bind改變后的指向父層滨巴。
2思灌、對state中的數(shù)據(jù)進(jìn)行賦值
在react中我們使用setState來更新數(shù)據(jù):
dataMsg:'原數(shù)據(jù)'
setData=()=>{
//此處使用setState來更新數(shù)據(jù)
this.setState({
dataMsg:'數(shù)據(jù)已被改變'
})
console.log(this.state.dataMsg)
}
但是console打印出來的值是:原數(shù)據(jù)。
這里就要提到react里setState的異步了恭取,在react里setState這個(gè)方法是異步的泰偿,不會(huì)按順序執(zhí)行,它可能會(huì)等待一組state一起進(jìn)行更新蜈垮,來提高性能耗跛。下面提供一個(gè)解決辦法,setState的回調(diào)setState(updater[, callback])攒发,相當(dāng)于componentDidUpdate函數(shù):
setData=()=>{
//此處使用setState來更新數(shù)據(jù)
//setState的回調(diào)setState(update, ()=>{//更新完后執(zhí)行的代碼})调塌,
this.setState({
dataMsg:'數(shù)據(jù)已被改變'
},()=>{
console.log(this.state.dataMsg)
}
}
3、方法的傳值
因?yàn)樵谑录惺褂胦nClick={this.setData()}時(shí)方法直接執(zhí)行惠猿,直接寫成this.setData(data)這樣會(huì)報(bào)錯(cuò)羔砾,所以需要使用bind():
//看參數(shù),第一個(gè)參數(shù)需要是this或是一個(gè)函數(shù)
//第二個(gè)參數(shù)為需要傳遞參數(shù)
bind(this: Function, thisArg: any, ...argArray: any[]): any)
下面看如何傳遞:
<button className="myFormEvent-setData2-btn" onClick={this.setData.bind(this,["第一個(gè)參數(shù)","第二個(gè)參數(shù)","第三個(gè)參數(shù)"])}>執(zhí)行方法傳值2</button>
//多個(gè)參數(shù)時(shí)str即為數(shù)組
setData=(str)=>{
this.state({
msg:str[0],
dataMsg:str[2]
})
}
二偶妖、事件對象
事件對象:在出發(fā)DOM上的某個(gè)事件時(shí)姜凄,會(huì)產(chǎn)生一個(gè)事件對象event,這個(gè)對象中包含著所有與事件有關(guān)的信息趾访。
1态秧、使用event.target獲取相關(guān)屬性值:
event.target.style.background //獲取或更改背景色
event.target.getAttribute("aid") //獲取自定義屬性的值
event.target.setAttribute("aid","aaa")//設(shè)置自定義屬性的值
e.target.value //獲取輸入框的值
//按鈕點(diǎn)擊事件
<button aid="aaa" onClick={this.getEvent}></button>
getEvent=(event)=>{
//使用event.target來改變顏色
event.target.style.background="red";
//使用event.target.getAttribute("aid")里獲取button的自定義屬性aid的值
//使用event.target.setAttribute("aid","aaa")來設(shè)置button的自定義屬性aid的值
console.log(event.target.getAttribute("aid"));
}
//輸入框改變事件
<input onChange={this.inputChange}></input>
inputChange=(e)=>{
//使用event.target.value獲取表單輸入值
console.log(e.target.value);
}
2、使用this.refs來獲取值
給標(biāo)簽添加ref屬性扼鞋,在事件里通過this.refs.[屬性].value來獲取值
<input ref="val" onChange={this.refChange}/><button onClick={this.getRefVal}>通過ref獲取輸入框的值</button>
refChange=()=>{
//獲取值
let str = this.refs.val.value;
this.setState({
val:str
})
}
3申鱼、event的部分事件
輸入框事件:
onChange:輸入框改變時(shí)觸發(fā)
鍵盤事件:
onKeyUp:按鍵抬起時(shí)觸發(fā)
onKeyDown:按鍵按下時(shí)觸發(fā)
點(diǎn)擊事件:
onClick:點(diǎn)擊時(shí)觸發(fā)
三愤诱、react的表單
1、雙向數(shù)據(jù)綁定
雙向數(shù)據(jù)綁定在vue中有捐友,在react中是沒有的淫半,雙向數(shù)據(jù)綁定就是雙方的數(shù)據(jù)改變相互影響,下面只是模擬雙向數(shù)據(jù)綁定:
//輸入框使用value時(shí)需要添加onChange監(jiān)聽事件
//還可以使用defaultValue
<input value={this.state.data} onChange={this.inputDataChange} /><button onClick={this.getInputData}>改變model數(shù)據(jù)為data</button><br/>
數(shù)據(jù)顯示:{this.state.data}<br/>
//初始化
constructor(props){
super(props);
this.state={
data:'data'
}
}
//輸入框值改變時(shí)改變state的值楚殿,視圖上相對改變
inputDataChange=(e)=>{
//此處是輸入框狀態(tài)改變的數(shù)據(jù)
this.setState({
data:e.target.value
})
}
//相當(dāng)于state的值改變撮慨,視圖上的值也改變
getInputData=()=>{
//此處是點(diǎn)擊時(shí)要改變的數(shù)據(jù)
this.setState({
data:'data'
})
}
上面的的value需要事件監(jiān)聽竿痰,這里面有一個(gè)react的知識(shí)點(diǎn):約束性組件和非約束性組件脆粥。
約束性組件,簡單說就是react管理了它的value影涉,而非約束性組件的value是由原生DOM管理的变隔。
約束性組件是這樣寫的:
<input value={this.state.data} onChange={this.inputDataChange} />
這里的value屬性不再是一個(gè)寫死的值,它是this.state.data,而this.state.data是由this.inputDataChange這個(gè)監(jiān)聽事件負(fù)責(zé)管理的蟹倾。
這個(gè)時(shí)候?qū)嶋H上 input 的 value 根本不是用戶輸入的內(nèi)容匣缘。而是onChange 事件觸發(fā)之后,由 this.setState 導(dǎo)致了一次重新渲染鲜棠。不過React會(huì)優(yōu)化這個(gè)渲染過程肌厨,實(shí)際它依然是通過設(shè)置input的value來實(shí)現(xiàn)的。
非約束性組件是這樣寫的:
<input defaultValue="a" />
這個(gè)defaultValue就是原生DOM中的value屬性豁陆,其value值就是用戶輸入的內(nèi)容柑爸,react不管理輸入的過程。
對比約束性組件和非約束性組件的輸入流程:
*約束性組件: 用戶輸入A -> 觸發(fā)onChange事件 -> inputDataChange 中設(shè)置 state.name = “A” -> 渲染input使他的value變成A
*非約束性組件: 用戶輸入A -> input 中顯示A
2盒音、react表單的寫法
這里介紹form表單里的幾種常用的子標(biāo)簽:
一般表單都是需要用form標(biāo)簽包起來:
<form></form>
- 阻止表單的默認(rèn)提交
有時(shí)我們需要阻止表單的默認(rèn)提交表鳍,來自己把握什么時(shí)候提交調(diào)用preventDefault()方法,如下:
<form onSubmit={this.doSubmit}></form>
doSubmit=(e)=>{
//使用事件e來調(diào) preventDefault()方法來阻止表單默認(rèn)提交
e.preventDefault();
}
- 文本框
設(shè)置value屬性祥诽,因?yàn)槭羌s束性組件譬圣,所以需要onChange觸發(fā)事件,下面的都是這樣
在事件方法handleName(event)里使用event.target.value來獲取輸入框中的值雄坪,如下:
constructou(props){
super(props);
this.state={
name:''
}
}
handleName=(e)=>{
this.setState({
name:e.target.value
})
}
姓名:<input type="text" value={this.state.name} onChange={this.handleName} />
- 單選框
單選框非手動(dòng)輸入厘熟,所以需要在標(biāo)簽上加入value屬性,否則獲取不到數(shù)據(jù)维哈。因?yàn)槲覀円x擇绳姨,所以要添加checked,來判斷選中狀態(tài):
constructou(props){
super(props);
this.state={
//默認(rèn)選中女
sex:'0'
}
}
/**
checked={this.state.sex==0}是判斷是否為選中狀態(tài)
當(dāng)點(diǎn)擊選中按鈕后獲取當(dāng)前選中的value值笨农,然后改變sex的值
react重新渲染后就缆,點(diǎn)擊的按鈕變?yōu)楸贿x中狀態(tài)
*/
handleSex=(e)=>{
this.setState({
sex:e.target.value
})
}
性別:<input type="radio" checked={this.state.sex==0} value="0" onChange={this.handleSex} />男
<input type="radio" checked={this.state.sex==1} value="1" onChange={this.handleSex} />女
- 下拉框
下拉框里的數(shù)據(jù)是數(shù)組,所以我們需要用到循環(huán)獲取谒亦,我們需要有個(gè)變量city來存儲(chǔ)選中的值竭宰,看代碼:
constructou(props){
super(props);
this.state={
city:'',
citys:[
'北京','上海','深圳'
]
}
}
handleCity=(e)=>{
this.setState({
city:e.target.value
})
}
/**
使用map()來循環(huán)數(shù)據(jù)空郊,注意map(function(value,key){})
的this的指向,此時(shí)的this是無法調(diào)用state的
注意:return中是需要一個(gè)根標(biāo)簽包裹的切揭,此處<option>即可
需要在option上添加key狞甚,map循環(huán)需要,以便更好的管理數(shù)據(jù)
*/
城市:
<select value={this.state.city} onChange={this.handleCity}>
{this.state.citys.map(function(value,key){
return(
<option key={key} >{value}</option>
)
})}
</select>
- 復(fù)選框
constructou(props){
super(props);
this.state={
hobby:[
{'title':'睡覺','checked':true},
{'title':'吃飯','checked':false},
{'title':'聽音樂','checked':false}
]
}
}
/**
hobby是個(gè)數(shù)組廓旬,我們通過key來找到選中狀態(tài)哼审,當(dāng)點(diǎn)擊時(shí)通過
hobby[key].checked = !hobby[key].checked;
來改變選中狀態(tài),然后將hobby重新賦值孕豹,和單選框類似
*/
handleHobby(key){
var hobby = this.state.hobby;
hobby[key].checked = !hobby[key].checked;
this.setState({
hobby:hobby
})
}
/**
因?yàn)槲覀冃枰猭ey來找到選項(xiàng)的選中狀態(tài)涩盾,所以我們需要把key傳到方法中,
此處使用箭頭函數(shù)將map函數(shù)中的this指向調(diào)整了励背,所以在return中可以是用this.handleHobby
*/
喜好:
{this.state.hobby.map((value,key)=>{
return(
<span key={key}>
<input type="checkbox" checked={value.checked} onChange={this.handleHobby.bind(this,key)}/>{value.title}
</span>
)
})}
- 文本域
和文本框類似:
constructou(props){
super(props);
this.state={
info:''
}
}
handleInfo=(e)=>{
this.setState({
info:e.target.value
})
}
info:<input type="textarea" value={this.state.info} onChange={this.handleInfo}/>
四春霍、react中的state和props
props
1、react的組件從概念上看就是一個(gè)函數(shù)叶眉,可以接受一個(gè)參數(shù)最為輸入值址儒,這個(gè)參數(shù)就是props,可以把props理解為從外部傳入組件內(nèi)部的數(shù)據(jù)衅疙。
2莲趣、props經(jīng)常被用作渲染組件和初始化狀態(tài),當(dāng)一個(gè)組件被實(shí)例化之后饱溢,它的props是只讀的喧伞,不可改變的。如果props在渲染過程中可以被改變理朋,會(huì)導(dǎo)致這個(gè)組件顯示的形態(tài)變得不可預(yù)測絮识。只有通過父組件重新渲染的方式才可以把新的props傳入組件中。
3嗽上、在組件中次舌,我們最好為props中的參數(shù)設(shè)置一個(gè)defaultProps,并且制定它的類型兽愤。
state
一個(gè)組件的顯示形態(tài)可以由數(shù)據(jù)狀態(tài)和外部參數(shù)所決定彼念,外部參數(shù)也就是props,而數(shù)據(jù)狀態(tài)就是state
state的主要作用是用于組件保存浅萧、控制以及修改自己的狀態(tài)逐沙,它只能在constructor中初始化,它算是組件的私有屬性洼畅,不可通過外部訪問和修改吩案,只能通過組件內(nèi)部的this.setState來修改,修改state屬性會(huì)導(dǎo)致組件的重新渲染帝簇。
寫在最后:
- 如果文章中有錯(cuò)誤或是表達(dá)不準(zhǔn)確的地方徘郭,歡迎大家評論中指正靠益,以便我完善。
- 文章我也會(huì)根據(jù)所學(xué)到新的知識(shí)不斷更新残揉。