處理事件

使用React元素處理事件和在DOM元素上處理事件非常相似。
有一些語(yǔ)法差異:

  • React事件使用駝峰式命名,而非小寫。
  • 在JSX中,你傳入一個(gè)函數(shù)作為時(shí)間處理器,而非一個(gè)字符串。
    舉個(gè)例子,下面這個(gè)HTML:
<button onclick="activateLasers()">
  Activate Lasers
</button>

在React中有些許不同:

<button onClick={activateLasers}>
  Activate Lasers
</button>

另外一處不同就是在React中你不能返回false來阻止默認(rèn)行為。你必須顯式地調(diào)用preventDefault。舉例來說,在簡(jiǎn)單的HTML中,如果你想阻止鏈接打開一個(gè)新頁(yè)面的這個(gè)默認(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是一個(gè)合成的事件。React依照W3C規(guī)則定義的這些合成事件,因此你無需擔(dān)心瀏覽器之間的兼容性。查看SyntheticEvent參考指南來了解更多。
在使用React時(shí),一般來說你不需要在一個(gè)DOM元素創(chuàng)建后調(diào)用addEventListener來為其添加監(jiān)聽器。而應(yīng)該在元素初始化渲染的時(shí)候提供一個(gè)監(jiān)聽器。
當(dāng)你使用ES6類去定義一個(gè)組件時(shí),一個(gè)事件處理器一般作為類的方法而存在。舉例來說,下面這個(gè)Toggle組件渲染一個(gè)可以讓用戶在"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上試一試
在JSX的回調(diào)函數(shù)中你必須格外小心this的含義。在JavaScript中,類方法默認(rèn)不會(huì)被綁定。如果你忘記綁定this.handleClick,然后將他傳遞給onClick,當(dāng)這個(gè)函數(shù)被調(diào)用時(shí),this將會(huì)是undefined。
這不只是React才有的行為;這是由于JavaScript中函數(shù)工作的方式導(dǎo)致的。通常情況下,如果你引用一個(gè)方法,但是后面沒有加上(),比如onClick={this.handleClick},那你就應(yīng)該綁定那個(gè)方法。
如果調(diào)用bind讓你很煩惱,這有兩個(gè)方法可以讓你解決這個(gè)問題。如果你正在使用還在試驗(yàn)階段的屬性初始化語(yǔ)法,那你就可以使用屬性初始化來正確的綁定回調(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>
    );
  }
}

創(chuàng)建React應(yīng)用中,這個(gè)語(yǔ)法是默認(rèn)開啟的。
如果你沒有在使用屬性初始值語(yǔ)法,也可以在回調(diào)函數(shù)中使用箭頭函數(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>
    );
  }
}

這種語(yǔ)法的問題就是每次LogginButton渲染的時(shí)候,都會(huì)創(chuàng)建一個(gè)不同的回調(diào)函數(shù)。多數(shù)情況下這都是可以接受的。但如果這個(gè)回調(diào)作為prop傳遞給下面的組件,下面的這些組件可能會(huì)進(jìn)行額外的重新渲染。我們通常建議在構(gòu)造函數(shù)中綁定或使用屬性初始器語(yǔ)法來避免這種性能問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容