深入React技術(shù)棧:事件系統(tǒng)

事件系統(tǒng)

之前了解過虛擬DOM在內(nèi)存中是以對象的形式存在坎背,那么給對象添加事件就會比較方便缓呛。React基于虛擬DOM實現(xiàn)了一種合成事件我們定義的所有事件處理器都會接收到一個事件對象的實例。

所有的事件都是綁定到最外層捎泻,如果需要訪問原生的事件對象,可以使用nativeEvent屬性埋哟。

  • 合成事件的綁定方式
<button onClick={this.handle.bind(this)}>button</button>

React并不會像DOM0級事件那樣將事件處理器直接綁定到HTML原生上笆豁,這里是一個函數(shù)指針。

  • 合成事件的實現(xiàn)機制

在React中赤赊,對合成事件做了兩件事情:事件委托和自動綁定渔呵。

1.事件委托
在React中,并不會把事件函數(shù)綁定到真實的節(jié)點上砍鸠,而是把所有的事件綁定到結(jié)構(gòu)的最外層扩氢,使用一個統(tǒng)一的事件監(jiān)聽器。該事件監(jiān)聽器維持了一個映射來保存所有組件內(nèi)部的事件監(jiān)聽爷辱。當組件的掛載和卸載的操作录豺,只是在該統(tǒng)一的事件監(jiān)聽器中刪除一寫對象。當事件發(fā)生時饭弓,首先被該事件監(jiān)聽器處理双饥,然后在該映射中找到真正的事件處理函數(shù)并調(diào)用。

2.自動綁定
React中每個方法的上下文都會指向該組件的實例弟断,即自動為this綁定到當前的組件咏花。而且React還會對這種綁定進行緩存。如果使用es6的方式創(chuàng)建組件阀趴,那么這種自動綁定不會存在昏翰,這樣我們就需要手動進行綁定。

import {Component} from 'react'

class App extends Component {
    constructor(props) {
        super(props)
    }
    
    handle() {
        
    }
    
    render() {
        return (
            <button disabled onClick={this.handle.bind(this)}></button>
        )
    }
}

我們還可以在構(gòu)造器內(nèi)完成this的綁定刘急,這樣就不用每次調(diào)用事件監(jiān)聽器的時候都要進行綁定棚菊。

import {Component} from 'react'

class App extends Component {
    constructor(props) {
        super(props)

        this.handle = this.handle.bind(this)  //構(gòu)造器中完成
    }

    handle() {

    }

    render() {
        return (
            <button disabled onClick={this.handle}></button>
        )
    }
}

我們還可以通過箭頭函數(shù),它會自動綁定此函數(shù)作用域的this叔汁,因此我們不需要對他使用bind方法统求。

  • 在React中使用原生事件
    在React的生命周期中检碗,在componentDidMount方法中完成組件的加載和渲染,存在真實的DOM码邻,此時我們可以完成事件的綁定折剃。

注意,在React中使用DOM原生事件的時候像屋,我們一定要在組件卸載的時候手動一處微驶,否則會出現(xiàn)內(nèi)存泄漏的問題,通過合成事件系統(tǒng)則不需要开睡,React內(nèi)部會幫我們進行處理因苹。

  • 合成事件和原生事件混用

之前做了一個項目,實現(xiàn)一個下拉框篇恒,點擊下拉框的時候下拉框顯示扶檐,但是點擊屏幕其他部分的時候下拉框收起,如果我們給document綁定一個點擊事件胁艰,點擊的時候下拉框收起款筑。但是發(fā)現(xiàn)一個問題,如果這樣實現(xiàn)的話腾么,點擊下拉框的時候奈梳,下拉框依然會是收起狀態(tài),不會顯示解虱。

這是因為攘须,React合成事件系統(tǒng)的委托機制,在合成事件中僅僅是在最外層的容器進行了綁定殴泰,并且依賴事件的冒泡機制完成了委托于宙。所以我在點擊出現(xiàn)下拉框中的使用e.preventDefault()并沒有什么作用,因為在合成事件中該事件并不是綁定到了當前這個dom上悍汛,當前dom的事件只是對其的一個引用捞魁。

所以,我們要注意:

  1. 不要將合成事件和原生事件混用离咐。
  2. 可以通過e.target進行判斷谱俭。例如當前的事件元素是下拉框按鈕的話則return false。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宵蛀,一起剝皮案震驚了整個濱河市昆著,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌糖埋,老刑警劉巖宣吱,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窃这,死亡現(xiàn)場離奇詭異瞳别,居然都是意外死亡征候,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門祟敛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疤坝,“玉大人,你說我怎么就攤上這事馆铁∨苋啵” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵埠巨,是天一觀的道長历谍。 經(jīng)常有香客問我,道長辣垒,這世上最難降的妖魔是什么望侈? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮勋桶,結(jié)果婚禮上脱衙,老公的妹妹穿的比我還像新娘。我一直安慰自己例驹,他們只是感情好捐韩,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鹃锈,像睡著了一般荤胁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上屎债,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天寨蹋,我揣著相機與錄音,去河邊找鬼扔茅。 笑死已旧,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的召娜。 我是一名探鬼主播运褪,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼玖瘸!你這毒婦竟也來了秸讹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤雅倒,失蹤者是張志新(化名)和其女友劉穎璃诀,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔑匣,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡劣欢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年棕诵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凿将。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡校套,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出牧抵,到底是詐尸還是另有隱情笛匙,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布犀变,位于F島的核電站妹孙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏获枝。R本人自食惡果不足惜涕蜂,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望映琳。 院中可真熱鬧机隙,春花似錦、人聲如沸萨西。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谎脯。三九已至葱跋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間源梭,已是汗流浹背娱俺。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留废麻,地道東北人荠卷。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像烛愧,于是被迫代替她去往敵國和親油宜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容