另一篇總結:react 中的事件綁定 。 2019-05-16 更新
javascript
建議:在瞭解 js 的 this 取值後食用更佳。html
html 中的綁定事件的寫法:
java
<button onclick="activateLasers()"> // onClick = "xxxx()"
激活按鈕
</button>
react 中的寫法:react
<button onClick={activateLasers}> // onclick = { xxxx }
激活按鈕
</button>
在 React 中另外一個不一樣是你不能使用返回 false 的方式阻止默認行爲, 必須明確的使用 preventDefault。ide
例如,一般咱們在 HTML 中阻止連接默認打開一個新頁面,能夠這樣寫:函數
<a href="#" onclick="console.log('點擊連接'); return false"> // return false 點我 </a>
可是,在 react 中,阻止默認行爲必須得用下面的方式:this
function ActionLink() {
function handleClick(e) {
e.preventDefault(); // preventDefault()
console.log('連接被點擊');
}
return (
<a href="#" onClick={handleClick}>
點我
</a>
);
}
一樣,使用 React 的時候一般不須要使用 addEventListener 爲一個已建立的 DOM 元素添加監聽器。只須要在這個元素初始渲染的時候提供一個監聽器。spa
首先一個例子:code
class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; // 這邊綁定是必要的,這樣 `this` 才能在回調函數中使用
// 這是其中的一種寫法 this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(prevState => ({ // prevState 會在後面關於 setState 中詳細介紹 isToggleOn: !prevState.isToggleOn })); } render() { return ( <button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' : 'OFF'} </button> ); } } ReactDOM.render( <Toggle />, document.getElementById('example') );
爲何須要這樣寫?htm
個人見解是和 this、 bind() 以及 函數的執行符號 有關。函數執行的符號是 "()"。
1 1.爲何在以前的組件案例(入坑筆記(二)的 Clock 組件)中的 tick 方法不須要綁定?
你必須謹慎對待 JSX 回調函數中的 this,類的方法默認是不會綁定 this 的。若是你忘記綁定 this.handleClick 並把它傳入 onClick, 當你調用這個函數的時候 this 的值會是 undefined。
這並非 React 的特殊行爲;它是函數如何在 JavaScript 中運行的一部分。一般狀況下,若是你沒有在方法後面添加 () ,例如 onClick={this.handleClick},你應該爲這個方法綁定 this。
函數綁定的其餘兩種方法:
1.使用 ES6 的箭頭函數來定義組件中的函數(屬性初始化語法):
class LoggingButton extends React.Component { // 這個語法確保了 `this` 綁定在 handleClick 中 handleClick = () => { console.log('this is:', this); } render() { return ( <button onClick={this.handleClick}> Click me </button> ); } }
2.render 函數中使用回調函數(不建議使用):
class LoggingButton extends React.Component { handleClick() { console.log('this is:', this); } render() { // 這個語法確保了 `this` 綁定在 handleClick 中 return ( <button onClick={(e) => this.handleClick(e)}> // 這邊其實是執行了一個回調函數,在回調函數中執行 handleClick 方法 Click me </button> ); } }
兩種方式,等價:
1 <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> // 回調形式傳參 2 <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button> // bind() 形式傳參
值得注意的是,經過 bind 方式向監聽函數傳參,在類組件中定義的監聽函數,事件對象 e 要排在所傳遞參數的後面,例如:
class Popper extends React.Component{ constructor(){ super(); this.state = {name:'Hello world!'}; } preventPop(name, e){ //事件對象e要放在最後 e.preventDefault(); alert(name); } render(){ return ( <div> <p>hello</p> {/* 經過 bind() 方法傳遞參數。 */} <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a> </div> ); } }