事件監(jiān)聽(tīng)
在React.js里面監(jiān)聽(tīng)是一件很容易的事情,只需要在需要監(jiān)聽(tīng)事件的元素加上類似onClick的屬性,例如:
class Header extends Component {
handleClickOnTitle () {
console.log('Click on title.')
}
render () {
return (
<h1 onClick={this.handleClickOnTitle}>事件監(jiān)聽(tīng)</h1>
)
}
}
給h1標(biāo)簽加上了onClick屬性,onClick緊更著一個(gè)表達(dá)式,這個(gè)表達(dá)式返回一個(gè)Header這個(gè)組件的一個(gè)實(shí)例方法。當(dāng)用戶點(diǎn)擊h1標(biāo)簽的時(shí)候,控制臺(tái)上就會(huì)輸出Click on title,類似AngularJs里面的ngClick。
在 React.js 不需要手動(dòng)調(diào)用瀏覽器原生的 addEventListener 進(jìn)行事件監(jiān)聽(tīng)。React.js 幫我們封裝好了一系列的 on* 的屬性,當(dāng)你需要為某個(gè)元素監(jiān)聽(tīng)某個(gè)事件的時(shí)候,只需要簡(jiǎn)單地給它加上 on* 就可以了。而且你不需要考慮不同瀏覽器兼容性的問(wèn)題,React.js 都幫我們封裝好這些細(xì)節(jié)了。
但是,事件監(jiān)聽(tīng)只能加在普通的HTML標(biāo)簽上,而不能加在自定義的Component上,例如<Header onClick={...}>,這樣是沒(méi)有效果的。但是有辦法可以做到這樣的綁定,目前我還不知道。。。
event對(duì)象
事件監(jiān)聽(tīng)函數(shù)會(huì)被傳入一個(gè)event對(duì)象,這個(gè)對(duì)象和瀏覽器中監(jiān)聽(tīng)事件傳遞的對(duì)象基本是一致的,不過(guò)React.js將原聲的event對(duì)象封裝了一下,對(duì)外提供統(tǒng)一的API和屬性,我們同樣不用去關(guān)心瀏覽器兼容問(wèn)題。嘗試以下代碼查看效果:
class Header extends Component {
handleClickOnTitle (e) {
console.log(e.target.innerHTML)
}
render () {
return (
<h1 onClick={this.handleClickOnTitle}>事件監(jiān)聽(tīng)</h1>
)
}
}
點(diǎn)擊后,控制臺(tái)會(huì)輸出‘事件監(jiān)聽(tīng)’。
事件中的this
一般this表示對(duì)象本身,如果你嘗試在上述代碼中的方法handleClickOnTitle里將this打印出來(lái),會(huì)發(fā)現(xiàn)控制臺(tái)輸出的是undefine。
class Header extends Component {
handleClickOnTitle (e) {
console.log(this)
}
render () {
return (
<h1 onClick={this.handleClickOnTitle}>事件監(jiān)聽(tīng)</h1>
)
}
}
這是因?yàn)镽eact.js在調(diào)用方法時(shí),不是通過(guò)對(duì)象方法的方式調(diào)用的(this.handleClickOnTitle),而是直接通過(guò)調(diào)用函數(shù)(handleClickOnTitle)來(lái)執(zhí)行的。所以事件監(jiān)聽(tīng)函數(shù)內(nèi)并不能通過(guò)this來(lái)獲取實(shí)例。
如果想在事件函數(shù)中使用當(dāng)前的實(shí)例,就需要手動(dòng)將實(shí)例方法bind到當(dāng)前實(shí)例上,再傳入給React.js。
class Header extends Component {
handleClickOnTitle (e) {
console.log(this)
}
render () {
return (
<h1 onClick={this.handleClickOnTitle.bind(this)}>事件監(jiān)聽(tīng)</h1>
)
}
}
這樣實(shí)例方法就綁定了當(dāng)前實(shí)例this,便可以在實(shí)例方法中使用當(dāng)前實(shí)例的數(shù)據(jù)或方法。
也可以在bind的時(shí)候給事件監(jiān)聽(tīng)傳入?yún)?shù):
class Header extends Component {
handleClickOnTitle (word, e) {
console.log(this, word)
}
render () {
return (
<h1 onClick={this.handleClickOnTitle.bind(this, 'Hello')}>事件監(jiān)聽(tīng)</h1>
)
}
}
總結(jié)
為 React 的組件添加事件監(jiān)聽(tīng)是很簡(jiǎn)單的事情,你只需要使用 React.js 提供了一系列的 on* 方法即可。
React.js 會(huì)給每個(gè)事件監(jiān)聽(tīng)傳入一個(gè) event 對(duì)象,這個(gè)對(duì)象提供的功能和瀏覽器提供的功能一致,而且它是兼容所有瀏覽器的。
React.js 的事件監(jiān)聽(tīng)方法需要手動(dòng) bind 到當(dāng)前實(shí)例,這種模式在 React.js 中非常常用。