從 Vue 的視角學 React(三)—— 事件處理

若是要處理某個元素的 click 事件,原生 js 能夠直接爲該元素添加一個 onclick 函數 html

Vue 封裝了 v-on 指令,能夠簡化爲 @click 並添加相應的函數react

React 的開發思想是儘可能保留 js 的特性,因此事件處理也是用 onClick,只不過換成了駝峯命名segmentfault

但在實際使用的時候,還須要綁定 this,由此而產生了不少優化方案函數

 

1、傳統語法優化

原生 js 的事件命名是純小寫this

<button onclick="handleClick()">Click Me</button>

React 中的事件命名和原生 js 很相似,只是改爲了小駝峯的形式spa

<button onClick={this.handleClick}>Click Me</button>

須要特別留意的是,像 onClick 這樣以 on 開頭的原生事件,只能用在原生 HTML 標籤上,而不能用在自定義的組件標籤上3d

// 一般狀況下,若是你沒有在方法後面添加 (),例如 onClick={this.handleClick},你應該爲這個方法綁定 thiscode

 

在上面的這個 handleClick 函數中,若是直接打印 this,獲得的值會是 undefined 或者 nullhtm

這是由於 React 在調用事件處理函數的時候,並非從對象調用 this.handleClick,而是直接調用 handleClick

因此若是要操做 React.Component 實例 (即 this),好比 this.setState(),就須要 bind(this)

<button onClick={this.handleClick.bind(this, name, id)}>Click Me</button>

或者直接用箭頭函數

<button onClick={(e)=>this.handleClick(name, id, e)}>Click Me</button>

 

 

2、在構造函數中 bind(this)

若是把上面的代碼補充成一個完整的組件:

這裏直接在綁定 onClick 的處理函數的時候添加了 bind(this),位於 render() 函數內部

如此一來,每次調用的 render() 的時候,相應的函數都會執行一次 bind(this)

這是很是影響效率的操做,並且在某些場景下,會致使組件的 props 的數據異常

官方推薦的解決方案是,在構造函數裏面執行 bind(this)

但若是每個函數都須要 bind(this),這會是一件很是難受的事情,更優雅的作法是使用 Public Class Fields 語法

 

 

3、 Public Class Fields

上面的組件,在使用 Public Class Fields 語法會變得很是高效:

class TestButton extends React.Component { // 使用 public class fields 語法,不須要另外綁定 this handleClick = () => { console.log('this is:', this); } render() { return ( <button onClick={this.handleClick}>Click Me</button> ); } }

經過 Create React App 建立的項目,默認是支持這種語法的,能夠直接使用

只是這種語法還處於試驗階段,若是不肯冒險,最好是在構造函數中綁定 this

 

 

4、爲組件添加事件

上面有提到 onClick 只能在原生 HTML 中使用,在組件上使用是無效的

這是由於 React 的事件只能綁定到具體的 DOM 上,若是寫到組件上,只會被看成組件的 props 屬性

 

假設有一個組件 Child,若是要給它添加 onClick 的處理函數,能夠這麼寫:

class Child extends Component { render() { return ( <div onClick={this.props.onClick}/> ) } }

而後在父組件調用的時候,就能夠直接給 onClick 綁定處理事件了

<Child onClick={this.handleClick} />

 



參考資料:

《事件處理》

《React組件事件詳解》

相關文章
相關標籤/搜索