{% include './share/simple-component.md' %}
可以看到 React 里面綁定事件的方式和在 HTML
中綁定事件類似,使用駝峰式命名指定要綁定的 onClick
屬性為組件定義的一個(gè)方法 {this.handleClick.bind(this)}
。
注意要顯式調(diào)用 bind(this)
將事件函數(shù)上下文綁定要組件實(shí)例上,這也是 React
推崇的原則:沒有黑科技,盡量使用顯式的容易理解的 JavaScript 代碼。
React 實(shí)現(xiàn)了一個(gè)“合成事件”層(synthetic event system),這個(gè)事件模型保證了和 W3C 標(biāo)準(zhǔn)保持一致,所以不用擔(dān)心有什么詭異的用法,并且這個(gè)事件層消除了 IE 與 W3C 標(biāo)準(zhǔn)實(shí)現(xiàn)之間的兼容問題。
“合成事件”還提供了額外的好處:
事件委托
“合成事件”會(huì)以事件委托(event delegation)的方式綁定到組件最上層,并且在組件卸載(unmount)的時(shí)候自動(dòng)銷毀綁定的事件。
什么是“原生事件”?
比如你在 componentDidMount
方法里面通過 addEventListener
綁定的事件就是瀏覽器原生事件。
使用原生事件的時(shí)候注意在 componentWillUnmount
解除綁定 removeEventListener
。
所有通過 JSX 這種方式綁定的事件都是綁定到“合成事件”,除非你有特別的理由,建議總是用 React 的方式處理事件。
Tips
關(guān)于這兩種事件綁定的使用,這里有必要分享一些額外的人生經(jīng)驗(yàn)
如果混用“合成事件”和“原生事件”,比如一種常見的場(chǎng)景是用原生事件在 document
上綁定,然后在組件里面綁定的合成事件想要通過 e.stopPropagation()
來阻止事件冒泡到 document,這時(shí)候是行不通的,參見 Event
delegation,因?yàn)?e.stopPropagation
是內(nèi)部“合成事件” 層面的,解決方法是要用 e.nativeEvent.stopImmediatePropagation()
”合成事件“ 的 event
對(duì)象只在當(dāng)前 event loop
有效,比如你想在事件里面調(diào)用一個(gè) promise,在 resolve 之后去拿 event
對(duì)象會(huì)拿不到(并且沒有錯(cuò)誤拋出):
handleClick(e) {
promise.then(() => doSomethingWith(e));
}
詳情見 Event pooling 說明。
給事件處理函數(shù)傳遞額外參數(shù)的方式:bind(this, arg1, arg2, ...)
render: function() {
return <p onClick={this.handleClick.bind(this, 'extra param')}>;
},
handleClick: function(param, event) {
// handle click
}