?
This document uses PHP Chinese website manual Release
使用React元素處理事件與處理DOM元素上的事件非常相似。有一些語法差異:
React事件使用camelCase命名,而不是小寫。
使用JSX,您將傳遞函數(shù)作為事件處理函數(shù),而不是字符串。
例如,HTML:
<button onclick="activateLasers()"> Activate Lasers</button>
在React中略有不同:
<button onClick={activateLasers}> Activate Lasers</button>
另一個區(qū)別是,您無法返回false
以防止React中的默認(rèn)行為。您必須preventDefault
明確調(diào)用。例如,對于純HTML,為了防止打開新頁面的默認(rèn)鏈接行為,您可以編寫:
<a href="#" onclick="console.log('The link was clicked.'); return false"> Click me</a>
在React中,這可能是:
function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick}> Click me </a> ); }
這里e
是一個綜合事件。React根據(jù)W3C規(guī)范定義了這些合成事件,因此您不必?fù)?dān)心跨瀏覽器兼容性。請參閱SyntheticEvent
參考指南了解更多信息。
使用React時,通常不需要調(diào)用addEventListener
添加偵聽器到DOM元素后創(chuàng)建。相反,只需在元素初始呈現(xiàn)時提供偵聽器。
當(dāng)你使用ES6類定義一個組件時,一個常見的模式是讓一個事件處理器成為該類的一個方法。例如,這個Toggle
組件呈現(xiàn)一個按鈕,讓用戶在“ON”和“OFF”狀態(tài)之間切換:
class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; // This binding is necessary to make `this` work in the callback this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn }) ); } render() { return ( <button onClick={this.handleClick}>{this.state.isToggleOn ? 'ON' : 'OFF'}</button>); } } ReactDOM.render( <Toggle />, document.getElementById('root'));
在CodePen上試用它。
您必須小心this
JSX回調(diào)的含義。在JavaScript中,類方法默認(rèn)沒有綁定。如果你忘記綁定this.handleClick
并傳遞給它onClick
,this
將會在undefined
實際調(diào)用該函數(shù)時出現(xiàn)。
這不是特定于反應(yīng)的行為; 它是JavaScript中如何使用函數(shù)的一部分。一般來說,如果你引用一個沒有()
后面的方法,比如onClick={this.handleClick}
你應(yīng)該綁定那個方法。
如果打電話bind
讓你惱火,有兩種方法可以解決這個問題。如果您使用的是實驗性公共類字段語法,則可以使用類字段來正確地綁定回調(diào):
class LoggingButton extends React.Component { // This syntax ensures `this` is bound within handleClick. // Warning: this is *experimental* syntax. handleClick = () => { console.log('this is:', this); } render() { return ( <button onClick={this.handleClick}> Click me </button> ); }}
這個語法在Create React App中是默認(rèn)啟用的。
如果您不使用類字段語法,則可以在回調(diào)中使用箭頭函數(shù):
class LoggingButton extends React.Component { handleClick() { console.log('this is:', this); } render() { // This syntax ensures `this` is bound within handleClick return ( <button onClick={(e) => this.handleClick(e)}> Click me </button> ); } }
這個語法的問題是每次LoggingButton
渲染都會創(chuàng)建一個不同的回調(diào)函數(shù)。在大多數(shù)情況下,這很好。但是,如果將此回調(diào)作為道具傳遞給較低組件,則這些組件可能會進(jìn)行額外的重新渲染。我們通常建議在構(gòu)造函數(shù)中綁定或使用類字段語法來避免此類性能問題。
在循環(huán)內(nèi)部,通常需要將一個額外的參數(shù)傳遞給事件處理程序。例如,如果id
是行ID,則以下任一項都可以工作:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
以上兩行相同,分別使用箭頭函數(shù)和箭頭函數(shù)Function.prototype.bind
。
在這兩種情況下,e
表示React事件的參數(shù)都將作為ID之后的第二個參數(shù)傳遞。使用箭頭函數(shù),我們必須明確地傳遞它,但是bind
任何更多的參數(shù)都會自動轉(zhuǎn)發(fā)。