React 事件處理
另外一篇總結:react 中的事件綁定 。 2019-05-16 更新
建議:在了解 js 的 this 取值后食用更佳。
一、react 與 Html 中用法的異同和注意點
html 中的綁定事件的寫法:
<button onclick="activateLasers()"> // onClick = "xxxx()"
激活按鈕
</button>
react 中的寫法:
<button onClick={activateLasers}> // onclick = { xxxx }
激活按鈕
</button>
在 React 中另一個不同是你不能使用返回 false 的方式阻止默認行為, 必須明確的使用 preventDefault。
例如,通常我們在 HTML 中阻止鏈接默認打開一個新頁面,可以這樣寫:
<a href="#" onclick="console.log('點擊鏈接'); return false"> // return false
點我
</a>
但是,在 react 中,阻止默認行為必須得用下面的方式:
function ActionLink() {
function handleClick(e) {
e.preventDefault(); // preventDefault()
console.log('鏈接被點擊');
}
return (
<a href="#" onClick={handleClick}>
點我
</a>
);
}
同樣,使用 React 的時候通常不需要使用 addEventListener 為一個已創建的 DOM 元素添加監聽器。只需要在這個元素初始渲染的時候提供一個監聽器。
二、綁定事件處理函數
首先一個例子:
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')
);
為什么需要這樣寫?
我的看法是和 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>
);
}
}
