響應(yīng)事件處理

在react中,處理事件響應(yīng)的方式主要有: (1).?使用匿名函數(shù); (2).使用組件的方法; (3).?使用屬性初始化的語(yǔ)法;?

? ? (1).使用匿名函數(shù),

? ? ? ? 這是最簡(jiǎn)單的一種方式,哪里需要響應(yīng)事件就在哪里創(chuàng)建一個(gè)匿名函數(shù),

先看代碼:?

? handleChange(e){

? ? ? ? console.log("e",e);

? }

render(){

? return? ?<div>

? ? ? ? ? ? ? ? <Button onClick = {(e) => handleChange(e)}></Button>

????????</div>

}

????????點(diǎn)擊Button的事件響應(yīng)函數(shù)是一個(gè)匿名函數(shù)涵紊,這應(yīng)該是最常見(jiàn)的處理事件響應(yīng)的方式了。這種方式的好處是,簡(jiǎn)單直接肴掷。哪里需要處理事件響應(yīng)刨裆,就在哪里定義一個(gè)匿名函數(shù)處理司蔬。

????????在上面的代碼中,也可以不使用箭頭函數(shù),直接使用onClick = {function(){}}的形式,?但實(shí)際開(kāi)發(fā)中不會(huì)用到這種方式,因?yàn)榧^函數(shù)解決了this綁定的問(wèn)題耿战,可以將函數(shù)體內(nèi)的this綁定到當(dāng)前對(duì)象秸脱,而不是運(yùn)行時(shí)調(diào)用函數(shù)的對(duì)象芳绩。如果響應(yīng)函數(shù)中需要使用this.state,那么這種方式就無(wú)法正常運(yùn)行了撞反。所以項(xiàng)目中一般直接使用箭頭函數(shù)定義的匿名函數(shù)作為事件響應(yīng)妥色。

? ??????使用匿名函數(shù)的缺點(diǎn)是:當(dāng)事件響應(yīng)邏輯比較復(fù)雜時(shí),匿名函數(shù)的代碼量會(huì)很大遏片,會(huì)導(dǎo)致render函數(shù)變得臃腫嘹害,不容易直觀地看出組件最終渲染出的元素結(jié)構(gòu)。另外吮便,每次render方法調(diào)用時(shí)笔呀,都會(huì)重新創(chuàng)建一個(gè)匿名函數(shù)對(duì)象,帶來(lái)額外的性能開(kāi)銷(xiāo)髓需,當(dāng)組件的層級(jí)越低時(shí)许师,這種開(kāi)銷(xiāo)就越大,因?yàn)槿魏我粋€(gè)上層組件的變化都可能會(huì)觸發(fā)這個(gè)組件的render方法僚匆。當(dāng)然微渠,在大多數(shù)情況下,這點(diǎn)性能損失是可以不必在意的咧擂。

(2).使用組件方法:

? ? 毫無(wú)疑問(wèn),按鈕的響應(yīng)事件是直接調(diào)用組件的方法,這種方式需要通過(guò)在?constructor中手動(dòng)綁定this;

? ? 看代碼:

? ??constructor(props, context) {

? super(props, context);

? this.state = {

? ? options: {},

? }

? this.handleChange = this.handleChange.bind(this);

}

handleChange (e){

? console.log("e",e);

}

render(){

return <div>

? ? ? ? <button onClick={this.handleChange?}>功能介紹聽(tīng)您的</button>

</div>

}

????????點(diǎn)擊Button的事件響應(yīng)函數(shù)是組件的方法:handleClick逞盆。這種方式的好處是:每次render方法的調(diào)用,不會(huì)重新創(chuàng)建一個(gè)新的事件響應(yīng)函數(shù)松申,沒(méi)有額外的性能損失云芦。但是俯逾,使用這種方式要在構(gòu)造函數(shù)中為作為事件響應(yīng)的方法(handleClick),手動(dòng)綁定this: this.handleClick = this.handleClick.bind(this)舅逸,這是因?yàn)镋S6 語(yǔ)法的緣故桌肴,ES6 Class 的方法默認(rèn)不會(huì)把this綁定到當(dāng)前的實(shí)例對(duì)象上,需要我們手動(dòng)綁定琉历。每次都手動(dòng)綁定this是不是有點(diǎn)繁瑣坠七?好吧,讓我們來(lái)看下一種方式善已。

(3).?使用屬性初始化語(yǔ)法

? ??//代碼4

????class MyComponent extends React.Component{

? ??????state = {number: 0};

? handleClick = () => {

? ? this.setState({

? ? ? number: ++this.state.number

? ? });

? }

? render() {

? ? return (

<button onClick={this.handleClick}>功能介紹聽(tīng)您的</button>

? ? );

? }

}

說(shuō)明: 這里是利用的es7的屬性初始化語(yǔ)法,?從constructor里拿出來(lái)放到property initializer(屬性初始化器)里。我們可以看到這里沒(méi)有使用constructor函數(shù), 直接將state寫(xiě)在了外面.?constructor是ES6中類(lèi)的構(gòu)造函數(shù)离例。整個(gè)構(gòu)造函數(shù)需要一個(gè)參數(shù)props,其全部的值都在上文的代碼中給出:title艘包、image等耀盗。state = ...一句中,使用props初始化了整個(gè)組件的state初值舌厨。


擴(kuò)展:事件響應(yīng)函數(shù)的傳參問(wèn)題

事件響應(yīng)函數(shù)默認(rèn)是會(huì)被傳入一個(gè)事件對(duì)象Event作為參數(shù)的忿薇。如果想傳入其他參數(shù)給響應(yīng)函數(shù)應(yīng)該怎么辦呢?使用第一種方式的話(huà)很簡(jiǎn)單揉燃,直接使用新參數(shù):

//代碼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)=>(

    ? ? ? ? ? ? onClick={(event) => this.handleClick(item, event)}>{item}

    ? ? ? ? ? )

    ? ? ? ? )}

    ? ? );

    ? }

    }

    onClick的響應(yīng)函數(shù)中筋栋,方法體內(nèi)可以直接使用新的參數(shù)item弊攘。

    使用第二種方式的話(huà),可以把綁定this的操作延遲到render中氓栈,在綁定this的同時(shí)婿着,綁定額外的參數(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)=>(

      ? ? ? ? ? ? onClick={this.handleClick.bind(this, 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)=>(

        ? ? ? ? ? ? onClick={this.handleClick.bind(undefined, item)}>{item}

        ? ? ? ? ? )

        ? ? ? ? )}

        ? ? );

        ? }

        }

        ????????不過(guò)這種方式就有點(diǎn)雞肋了形纺,因?yàn)殡m然你不需要通過(guò)bind函數(shù)綁定this徒欣,但仍然要使用bind函數(shù)來(lái)綁定其他參數(shù)。

        ????????關(guān)于事件響應(yīng)函數(shù)脂新,還有一個(gè)地方需要注意粗梭。不管你在響應(yīng)函數(shù)中有沒(méi)有顯式的聲明事件參數(shù)Event,React都會(huì)把事件Event作為參數(shù)傳遞給響應(yīng)函數(shù)滞乙,且參數(shù)Event的位置總是在其他自定義參數(shù)的后面斩启。例如醉锅,在代碼6和代碼7中兔簇,handleClick的參數(shù)中雖然沒(méi)有聲明Event參數(shù)男韧,但你依然可以通過(guò)arguments[1]獲取到事件Event對(duì)象此虑。

        ????????總結(jié)一下口锭,三種事件處理的方式,第一種有額外的性能損失韭寸;第二種需要手動(dòng)綁定this荆隘,代碼量增多;第三種用到了ES7的特性晶渠,目前并非默認(rèn)支持,需要Babel插件的支持便瑟,但是寫(xiě)法最為簡(jiǎn)潔番川,也不需要手動(dòng)綁定this。一般推薦使用第二種和第三種方式践啄。

        參考文檔:? 1.?http://www.reibang.com/p/429b2326bf9b

        2.https://www.cnblogs.com/ikcamp/p/8989492.html

        3.?官方文檔:http://www.css88.com/react/docs/handling-events.html

        4.?https://segmentfault.com/q/1010000007247736/a-1020000007247989

        最后編輯于
        ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
        • 序言:七十年代末屿讽,一起剝皮案震驚了整個(gè)濱河市嚷节,隨后出現(xiàn)的幾起案子硫痰,更是在濱河造成了極大的恐慌,老刑警劉巖效斑,帶你破解...
          沈念sama閱讀 218,525評(píng)論 6 507
        • 序言:濱河連續(xù)發(fā)生了三起死亡事件柱徙,死亡現(xiàn)場(chǎng)離奇詭異护侮,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)羊初,發(fā)現(xiàn)死者居然都...
          沈念sama閱讀 93,203評(píng)論 3 395
        • 文/潘曉璐 我一進(jìn)店門(mén)晦攒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)得哆,“玉大人,你說(shuō)我怎么就攤上這事栋操。” “怎么了绎巨?”我有些...
          開(kāi)封第一講書(shū)人閱讀 164,862評(píng)論 0 354
        • 文/不壞的土叔 我叫張陵蠕啄,是天一觀的道長(zhǎng)歼跟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)留瞳,這世上最難降的妖魔是什么骚秦? 我笑而不...
          開(kāi)封第一講書(shū)人閱讀 58,728評(píng)論 1 294
        • 正文 為了忘掉前任作箍,我火速辦了婚禮胞得,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘跃巡。我一直安慰自己牧愁,他們只是感情好,可當(dāng)我...
          茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
        • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著办龄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪安接。 梳的紋絲不亂的頭發(fā)上盏檐,一...
          開(kāi)封第一講書(shū)人閱讀 51,590評(píng)論 1 305
        • 那天,我揣著相機(jī)與錄音材失,去河邊找鬼硫豆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛旨别,可吹牛的內(nèi)容都是我干的秸弛。 我是一名探鬼主播递览,決...
          沈念sama閱讀 40,330評(píng)論 3 418
        • 文/蒼蘭香墨 我猛地睜開(kāi)眼瞳腌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了纯趋?” 一聲冷哼從身側(cè)響起吵冒,我...
          開(kāi)封第一講書(shū)人閱讀 39,244評(píng)論 0 276
        • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤痹栖,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后揪阿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體南捂,經(jīng)...
          沈念sama閱讀 45,693評(píng)論 1 314
        • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溺健,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
          茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
        • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钮蛛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鞭缭。...
          茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
        • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剖膳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出岭辣,到底是詐尸還是另有隱情吱晒,我是刑警寧澤,帶...
          沈念sama閱讀 35,723評(píng)論 5 346
        • 正文 年R本政府宣布沦童,位于F島的核電站仑濒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏偷遗。R本人自食惡果不足惜躏精,卻給世界環(huán)境...
          茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
        • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鹦肿。 院中可真熱鬧矗烛,春花似錦、人聲如沸瞭吃。這莊子的主人今日做“春日...
          開(kāi)封第一講書(shū)人閱讀 31,919評(píng)論 0 22
        • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)浆洗。三九已至抠刺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間罕容,已是汗流浹背。 一陣腳步聲響...
          開(kāi)封第一講書(shū)人閱讀 33,042評(píng)論 1 270
        • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屁擅。 一個(gè)月前我還...
          沈念sama閱讀 48,191評(píng)論 3 370
        • 正文 我出身青樓胶果,卻偏偏與公主長(zhǎng)得像早抠,于是被迫代替她去往敵國(guó)和親作瞄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子羊赵,可洞房花燭夜當(dāng)晚...
          茶點(diǎn)故事閱讀 44,955評(píng)論 2 355