事件處理函數綁定
- DOM事件處理
addEventListener
oronclick = function(){}
純小寫 - React元素也采用了類似DOM0標準中的事件屬性定義的方法 小駝峰
- JSX
<button onClick={ this.doSth }></button>
- 直接創建React元素
React.createElement('button',{onClick: { this.doSth }},'按鈕'
)
阻止a標簽默認行為
- a標簽錨點
class MyAlink extends React.Component {handleClick() {console.log('點擊')}render() {return <a href="#" onClick={this.handleClick}>a鏈接</a>}
}
ReactDOM.render(<MyAlink />,document.getElementById('app')
)
- 使用偽協議在React中會報warning
<a href="javascript:;" onClick={this.handleClick}>a鏈接</a>
- 阻止默認事件 e(React事件對象,并非js原生的e)
class MyAlink extends React.Component {handleClick(e) {e.preventDefault()console.log('點擊', e)}render() {return <a href="#" onClick={this.handleClick}>a鏈接</a>}
}
事件對象
- SyntheticBaseEvent 合成基礎事件對象
- 這個SBE是遵守W3C事件對象的規范的,不存在任何的瀏覽器兼容性問題
React為什么要將事件處理直接綁定在元素上
- React認為事件處理和視圖有直接關系,寫在一起可以更直觀地表述視圖與邏輯的關系,便于維護
this指向
- ES6 class模塊默認不對事件處理函數進行this的再綁定
class MyButton extends React.Component {handleClick() {console.log('this', this)// this默認undefined}render() {return <button onClick={this.handleClick}>按鈕</button>}
}
ReactDOM.render(<MyButton />,document.getElementById('app')
)
function outerClick() {console.log('outher-this', this)// 依然是undefined
}
class MyButton extends React.Component {render() {return <button onClick={outerClick}>按鈕</button>}
}
ReactDOM.render(<MyButton />,document.getElementById('app')
)
- DOM0事件
// this指向button
<button onclick="console.log(this)">123</button>
解決this指向 建議使用134
- 在構造器中bind this 隱式傳入e
- 在視圖中bind this 隱式傳入e
- 回調 + 箭頭函數 + 方法執行(render函數每次執行時都會創建新的回調)
注意:給子組件的屬性傳遞函數時,由于每次都創建一個回調,子組件每次都接收一個新的函數,可能觸發子組件的render 顯式傳入e - class field寫法:class內部的箭頭函數
事件對象都在最后一個參數
// 在構造器中bind this
class MyButton extends React.Component {constructor(props) {super(props)this.handleClick = this.handleClick.bind(this)}handleClick() {console.log('this', this)// this指向類MyButton}render() {return <button onClick={this.handleClick}>按鈕</button>}
}
// 在視圖中bind this
class MyButton extends React.Component {constructor(props) {super(props)}handleClick(e) {// bind方法要使用e,無須傳入,是隱式傳入的 console.log('this', this, e)// this指向類MyButton}render() {return <button onClick={this.handleClick.bind(this)}>按鈕</button>}
}
// 回調 + 箭頭函數 + 方法執行
class MyButton extends React.Component {constructor(props) {super(props)}handleClick(e) {// 要使用e則需要傳入econsole.log('this', this)// this指向類MyButton}render() {return <button onClick={(e) => this.handleClick(e)}>按鈕</button>}
}
- 用在子組件上時,父組件每次render都創建一個新的回調,fn是響應的,會觸發子組件的render
render() {return (<div><button onClick={() => this.handleClick()}>按鈕</button><Title fn={() => this.doSth} /></div>)}
// class內部的箭頭函數
class MyButton extends React.Component {constructor(props) {super(props)}// 實驗性寫法outerClick = () => {console.log('outher-this', this)// 箭頭函數的this是穩定的 指向button}render() {return (<div><button onClick={this.outerClick}>按鈕</button></div>)}
}