鍍金池/ 教程/ HTML/ 事件處理
React 組件
Redux 的基礎(chǔ)概念
JSX
DOM 操作
在 React 應(yīng)用中使用 Redux
進(jìn)化 Flux
Webpack 配置 React 開發(fā)環(huán)境
服務(wù)器端渲染
組合組件
表單
屬性擴(kuò)散
開發(fā)環(huán)境配置
組件生命周期
Data Flow
JSX 與 HTML 的差異
組件間通信
使用 JSX
事件處理
Flux
React 概覽
Mixins
Redux

事件處理

{% 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ù)傳遞額外參數(shù)的方式:bind(this, arg1, arg2, ...)

render: function() {
    return <p onClick={this.handleClick.bind(this, 'extra param')}>;
},
handleClick: function(param, event) {
    // handle click
}

React 支持的事件列表