成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

如何優(yōu)雅地在React中處理事件響應(yīng)

buildupchao / 1347人閱讀

摘要:處理事件響應(yīng)是應(yīng)用中非常重要的一部分。中,處理事件響應(yīng)的方式有多種。關(guān)于事件響應(yīng)的回調(diào)函數(shù),還有一個地方需要注意。不管你在回調(diào)函數(shù)中有沒有顯式的聲明事件參數(shù),都會把事件作為參數(shù)傳遞給回調(diào)函數(shù),且參數(shù)的位置總是在其他自定義參數(shù)的后面。

React中定義一個組件,可以通過React.createClass或者ES6的class。本文討論的React組件是基于class定義的組件。采用class的方式,代碼結(jié)構(gòu)更加清晰,可讀性強(qiáng),而且React官方也推薦使用這種方式定義組件。

處理事件響應(yīng)是Web應(yīng)用中非常重要的一部分。React中,處理事件響應(yīng)的方式有多種。

1.使用箭頭函數(shù)

先上代碼:

//代碼1
class MyComponent extends React.Component {

  render() {
    return (
      
    );
  }
}

當(dāng)事件響應(yīng)邏輯比較復(fù)雜時,再把所有的邏輯直接寫在onClick的大括號內(nèi),就會導(dǎo)致render函數(shù)變得臃腫,不容易直觀地看出組件render出的元素結(jié)構(gòu)。這時,可以把邏輯封裝成組件的一個方法,然后在箭頭函數(shù)中調(diào)用這個方法。如下所示:

//代碼2
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {number: 0};
  }

  handleClick() {
    this.setState({
      number: ++this.state.number
    });
  }
  
  render() {
    return (
      
{this.state.number}
); } }

這種方式最大的問題是,每次render調(diào)用時,都會重新創(chuàng)建一個事件的回調(diào)函數(shù),帶來額外的性能開銷,當(dāng)組件的層級越低時,這種開銷就越大,因為任何一個上層組件的變化都可能會觸發(fā)這個組件的render方法。當(dāng)然,在大多數(shù)情況下,這點(diǎn)性能損失是可以不必在意的。這種方式也有一個好處,就是不需要考慮this的指向問題,因為這種寫法保證箭頭函數(shù)中的this指向的總是當(dāng)前組件。

2.使用組件方法

代碼先:

//代碼3
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {number: 0};
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({
      number: ++this.state.number
    });
  }
  
  render() {
    return (
      
{this.state.number}
); } }

這種方式的好處是每次render,不會重新創(chuàng)建一個回調(diào)函數(shù),沒有額外的性能損失。需要注意的是,使用這種方式要在構(gòu)造函數(shù)中為事件回調(diào)函數(shù)綁定this: this.handleClick = this.handleClick.bind(this),否則handleClick中的this是undefined。這是因為ES6 語法的緣故,ES6 的 Class 構(gòu)造出來的對象上的方法默認(rèn)不綁定到 this 上,需要我們手動綁定。每次都手動綁定this是不是有點(diǎn)蛋疼?好吧,讓我們來看下一種方式。

3.屬性初始化語法(property initializer syntax)

使用ES7的 property initializers,代碼可以這樣寫:

//代碼4
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {number: 0};
  }

  handleClick = () => {
    this.setState({
      number: ++this.state.number
    });
  }
  
  render() {
    return (
      
{this.state.number}
); } }

哈哈,再也不用手動綁定this了。但是你需要知道,這個特性還處于試驗階段,默認(rèn)是不支持的。如果你是使用官方腳手架Create React App 創(chuàng)建的應(yīng)用,那么這個特性是默認(rèn)支持的。你也可以自行在項目中引入babel的transform-class-properties插件獲取這個特性支持。

4.回調(diào)函數(shù)傳參問題

事件的回調(diào)函數(shù)默認(rèn)是會被傳入一個事件對象Event作為參數(shù)的。如果我想傳入其他參數(shù)給回調(diào)函數(shù)應(yīng)該怎么辦呢?

使用第一種方式的話很簡單,直接傳就可以了:

//代碼5
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [1,2,3,4],
      current: 1
    };
  }
  
  handleClick(item,event) {
    this.setState({
      current: item
    });
  }

  render() {
    return (
      
    {this.state.list.map( (item)=>(
  • this.handleClick(item, event)}>{item}
  • ) )}
); } }

使用第二種方式的話,可以把綁定this的操作延遲到render中,在綁定this的同時,綁定額外的參數(shù):

//代碼6
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [1,2,3,4],
      current: 1
    };
  }
  
  handleClick(item) {
    this.setState({
      current: item
    });
  }

  render() {
    return (
      
    {this.state.list.map( (item)=>(
  • {item}
  • ) )}
); } }

使用第三種方式,解決方案和第二種基本一致:

//代碼7
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [1,2,3,4],
      current: 1
    };
  }
  
  handleClick = (item) =>  {
    this.setState({
      current: item
    });
  }

  render() {
    return (
      
    {this.state.list.map( (item)=>(
  • {item}
  • ) )}
); } }

不過這種方式就有點(diǎn)雞肋了,因為雖然你不需要通過bind函數(shù)綁定this,但仍然要使用bind函數(shù)來綁定其他參數(shù)。

關(guān)于事件響應(yīng)的回調(diào)函數(shù),還有一個地方需要注意。不管你在回調(diào)函數(shù)中有沒有顯式的聲明事件參數(shù)Event,React都會把事件Event作為參數(shù)傳遞給回調(diào)函數(shù),且參數(shù)Event的位置總是在其他自定義參數(shù)的后面。例如,在代碼6和代碼7中,handleClick的參數(shù)中雖然沒有聲明Event參數(shù),但你依然可以通過arguments[1]獲取到事件Event對象。

總結(jié)一下,三種綁定事件回調(diào)的方式,第一種有額外的性能損失;第二種需要手動綁定this,代碼量增多;第三種用到了ES7的特性,目前并非默認(rèn)支持,需要Babel插件的支持,但是寫法最為簡潔,也不需要手動綁定this。推薦使用第二種和第三種方式。

歡迎關(guān)注我的公眾號:老干部的大前端,領(lǐng)取21本大前端精選書籍!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84239.html

相關(guān)文章

  • 如何優(yōu)雅安全地在深層數(shù)據(jù)結(jié)構(gòu)取值

    摘要:如果這個結(jié)構(gòu)非常復(fù)雜,那么想要安全優(yōu)雅地取出一個值,也并非簡單。這是為了在對象中相關(guān)取值的過程,需要驗證每一個和的存在性。并且這個數(shù)據(jù)結(jié)構(gòu)必然是動態(tài)生成的,存在有時有時的情況。在測試過程中,很難復(fù)現(xiàn)。 古有趙子龍面對沖鋒之勢,有進(jìn)無退,陷陣之志,有死無生的局面,能萬軍叢中取敵將首級。在我們的Javascript中,往往用對象(Object)來存儲一個數(shù)據(jù)結(jié)構(gòu)。如果這個結(jié)構(gòu)非常復(fù)雜,那么...

    RobinQu 評論0 收藏0
  • 如何優(yōu)雅安全地在深層數(shù)據(jù)結(jié)構(gòu)取值

    摘要:如果這個結(jié)構(gòu)非常復(fù)雜,那么想要安全優(yōu)雅地取出一個值,也并非簡單。這是為了在對象中相關(guān)取值的過程,需要驗證每一個和的存在性。并且這個數(shù)據(jù)結(jié)構(gòu)必然是動態(tài)生成的,存在有時有時的情況。在測試過程中,很難復(fù)現(xiàn)。 古有趙子龍面對沖鋒之勢,有進(jìn)無退,陷陣之志,有死無生的局面,能萬軍叢中取敵將首級。在我們的Javascript中,往往用對象(Object)來存儲一個數(shù)據(jù)結(jié)構(gòu)。如果這個結(jié)構(gòu)非常復(fù)雜,那么...

    liaorio 評論0 收藏0
  • 如何優(yōu)雅處理前端的異常?

    摘要:二需要處理哪些異常對于前端來說,我們可做的異常捕獲還真不少??偨Y(jié)一下,大概如下語法錯誤代碼異常請求異常靜態(tài)資源加載異常異常異??缬虮罎⒑涂D下面我會針對每種具體情況來說明如何處理這些異常。 前端一直是距離用戶最近的一層,隨著產(chǎn)品的日益完善,我們會更加注重用戶體驗,而前端異常卻如鯁在喉,甚是煩人。一、為什么要處理異常?異常是不可控的,會影響最終的呈現(xiàn)結(jié)果,但是我們有充分的理由去做這樣的事...

    zoomdong 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<