react入坑之事件
阿新 • • 發佈:2019-02-12
1 基本用法
在React中繫結事件跟直接在HTML中繫結事件非常相似,定義一個事件處理函式,並在JSX中繫結它:
function Greeting () {
function sayHi(e) {
e.preventDefault()
console.log('Hi!')
}
return (
<a onClick={Greeting}>Click me to say hi!</a>
)
}
所有事件繫結屬性比如onClick
均使用駝峰寫法(camelCase),事件繫結屬性的值不是字串而是事件處理函式名稱,可以帶上()
並傳參,無引數時可省略()
2 使用類定義元件時事件處理函式this
的指向問題
使用ES6的class
特性定義元件時,通常的做法是將事件處理函式當作該類的方法寫在類中。但需要注意的是方法的this
指向。
定義在類中的方法的預設的this
指向的是當前的類的例項,但事件處理函式因為是繫結到了具體的元素上,就會丟失定義時this
的指向。如果你的處理函式中使用了this
關鍵字來指向當前元件例項,那麼你需要手動將該方法的this
繫結到當前元件例項,有三種方法可以進行繫結:
1)在類的constructor中呼叫或在JSX中呼叫Function.prototype.bind()
手動繫結
2)在JSX的事件繫結屬性中的事件處理函式外層再套一個箭頭函式,在其中返回處理函式呼叫結果class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; this.handleClick = this.handleClick.bind(this); // 手動繫結 } handleClick() { // console.log(this) this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); } render() { return ( // <button onClick={this.handleClick.bind(this)}> // 在這裡繫結也可以 <button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' : 'OFF'} </button> ); } } ReactDOM.render( <Toggle />, document.getElementById('content') );
render() {
return (
<button onClick={(e) => this.handleClick(e)}> // 這麼繫結也行
Click me
</button>
);
}
3)Babel提供的一個ES8+的實驗性質的寫法
class LoggingButton extends React.Component { handleClick = () => { // 純粹的實驗性質的寫法,需要babel的支援 console.log('this is:', this); } render() { return ( <button onClick={this.handleClick}> Click me </button> ); } }
3 事件物件
React的事件物件是一個完全由React給出的事件物件,該物件對各個瀏覽器做了相容,同時保留了標準事件物件的介面,詳細資訊可以檢視React官網的參考。使用時需要關心的是如何在事件處理函式中使用事件物件。
在事件繫結的JSX中,處理函式接受一個名為event
的引數來表示事件物件,可以認為event
在事件繫結插值中屬於React的保留字,如果需要往事件處理函式中傳遞更多引數,請使用其他識別符號。
另外,7.2小節中不同的事件繫結寫法也對事件物件的處置略有不同,主要體現在事件繫結JSX中:
// 無括號
<button onClick={this.handleClick}>
Click me
</button>
// 帶括號
<button onClick={this.handleClick(event)}>
Click me
</button>
// 呼叫了bind()
<button onClick={this.handleClick.bind(this, event)}>
Click me
</button>
- 當事件繫結插值中的處理函式省略了
()
時,處理函式預設接受一個表示事件物件的引數, - 當事件繫結插值中的處理函式未省略
()
時,則需要顯示地使用保留字event
來傳入事件物件,未傳入則為undefined
;注意,不管有沒有在constructor
中繫結this
,直接在處理函式名後加()
會導致頁面初始化時該函式被立即執行一次,可能會有意想不到的錯誤,比如不能呼叫setState()
方法等,所以強烈不建議用這種寫法 - 當事件繫結插值中的處理函式呼叫了
bind()
時,可以顯示地使用保留字event
來傳入事件物件,否則React會在bind()
函式引數序列的末尾預設增加一個表示事件物件的引數
最後,在React中不能通過return false
來阻止預設事件,而是需要在事件處理函式中顯式呼叫event.preventDefault()
。