淺析React之事件系統(tǒng)(一)

大家周末好特石,2016年的最后幾篇文章開始寫到了React的一些東西吊说,那么最近就來一些圖表君對于React的簡單總結(jié)和理解,那么今天就開始第一篇钓瞭,說一說React的事件系統(tǒng)。

總覽

簡單來說React實現(xiàn)了一個SyntheticEvent層淫奔,所有定義的事件處理器都可以接受到一個SyntheticEvent對象的實例山涡,他是一個跨瀏覽器的對于原生事件的包裝,和原生事件一樣有同樣的接口,包括stopPropagation()和preventDefault()鸭丛。

合成事件的使用方式

在React中不會把所有的事件處理器綁定到相應(yīng)的真實的DOM節(jié)點上竞穷,而是使用一個統(tǒng)一的事件監(jiān)聽器,把所有的事件綁定在最外層鳞溉。當(dāng)事件發(fā)生的時候瘾带,首先被這個統(tǒng)一的事件監(jiān)聽器處理,隨后找到真正的事件處理函數(shù)進行調(diào)用熟菲,這樣是為了提高效率月弛,這是因為在UI系統(tǒng)中,事件處理器越多科盛,那么占據(jù)的內(nèi)存就越大帽衙,React的做法是將其簡化為一個,這樣就大大提高了效率贞绵。在之前開發(fā)者需要為了優(yōu)化性能需要自己來優(yōu)化自己的事件處理器的代碼厉萝,現(xiàn)在React幫助你完成了這些工作。

合成事件的綁定方式

說了這么許多理論上的知識榨崩,我們來看看合成事件是怎么使用的谴垫。

  1. bind方法。

    我們來直接看代碼

    
import React, {Component} from 'react';
        
class EventApp extends Component {
        
    handleClick(e,args){
        console.log('this is the react event',e)
        console.log('this is the args', args)
    }
        
        
    render(){
        return <button onClick={this.handleClick.bind(this,'test')}>Test</button>
    }
        
}
        
    
  1. 構(gòu)造器內(nèi)聲明

    再來看代碼


import React, {Component} from 'react';
        
    class EventApp extends Component {
        
        constructor(props){
                super(props);
                
                this.handleClick = this.handleClick.bind(this);
        }
        
        handleClick(e){
                console.log('this is the react event',e)
        }
        
        
        render(){
                return <button onClick={this.handleClick}>Test</button>
        }
        
 }

使用構(gòu)造器內(nèi)聲明的方法母蛛,僅僅要綁定一次而不需要每次使用的時候都綁定一次翩剪。

  1. 箭頭函數(shù)
class ButtonApp extends React.Component {

    handleClick (e) {
        console.log(e.target.value)
    }
 
    render(){
        return <button onClick={(e) => this.handleClick(e)}>Test</button>;
        }
    }
    

從上邊的使用方式我們可以看出React來使用合成事假還是很簡單的,但是現(xiàn)實的世界總是更加的復(fù)雜的彩郊。那么在React中我們可以使用原始事件嗎前弯?當(dāng)然是可以的。

使用原生事件

在React中我們也可以使用原生事件秫逝,那么如何進行綁定呢恕出,因為React提供了ComponentDidMount這樣的API讓我們可以調(diào)用,那么要使用原生事件我們就可以在DidMount后進行綁定违帆。例如上邊的那個例子中如果我們想把click事件綁定在原生button上該怎么做呢浙巫?我們來看代碼:

class ButtonApp extends React.Component {
    
    componentDidMount(){
        this.refs.button.addEventListener('click'  e => {
            console.log(e);
        })
    }
    
    componentWillUnmount(){
        this.refs.button.removeEventListener('click')
    }

    render(){
        return <button ref="button">Test</button>
    }

}

在這里例子中我們使用原生事件的方法綁到了button上,注意一點的是在DidMount上add了這個listener在willUnmont上remove這個listener刷后。一定要手動的記住移除的畴,不然可能會出現(xiàn)內(nèi)存泄漏問題。如果我們使用React合成事件尝胆,這些事React已經(jīng)幫你做好了丧裁。但是現(xiàn)實的情況下我們有一些場景是不得不用到原生的事件的那么該怎么做呢?

我們來看下邊的一個例子班巩。例如我們要實現(xiàn)這樣的一個功能渣慕,在頁面上有個button嘶炭,當(dāng)點擊它會出現(xiàn)一個圖片。當(dāng)點擊頁面的其他部分的時候逊桦,這個圖片會自動的消失眨猎,那么這樣的需求我們就不得不使用原生的事件了。話不多說我們來看代碼實現(xiàn)强经。

import React from 'react';

class App extends React.Component {

  constructor(props){
    super(props);
    
    this.state = {
      show: false
    }
    
    this.handleClick = this.handleClick.bind(this)
    this.handleClickImage = this.handleClickImage.bind(this);
  }
  
  handleClick(){
   this.setState({
     show: true
   })
  }
  
  componentDidMount(){
    document.body.addEventListener('click', e=> {
      this.setState({
        show: false
      })
    })
  }
  
  componentWillUnmount(){
    document.body.removeEventListener('click');
  }
    
  render(){
    return (
      <div className="container">
        <button onClick={this.handleClick}>Open Image</button>
          <div className="img-container" style={{ display: this.state.show ? 'block': 'none'}} >
            ![](http://upload-images.jianshu.io/upload_images/65230-86cf2d60ac48f213.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
          </div>
      </div>
    )
  }
}
ReactDOM.render(<App />, document.getElementById('root'));

Open In CodePen

上邊一個例子中睡陪,我們實現(xiàn)了組件APP,他里邊有一個button匿情,它上邊有一個handleClick的事件處理器兰迫,當(dāng)觸發(fā)時會把app的state里show制成true,這樣圖片就顯示了出來炬称。同時在body上使用了原生事件汁果,當(dāng)發(fā)生點擊事件的時候,就會被收起玲躯,這樣就簡單實現(xiàn)了需求的功能据德,那是看似這樣好像就沒有問題的,但是這其中有個bug跷车,到底是什么問題呢棘利,我們下篇文章繼續(xù)。看看原生事件和合成事件混用的那些事。

參考文獻:
深入react技術(shù)棧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末科乎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子茅郎,更是在濱河造成了極大的恐慌,老刑警劉巖誓斥,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件只洒,死亡現(xiàn)場離奇詭異,居然都是意外死亡劳坑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門成畦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來距芬,“玉大人,你說我怎么就攤上這事循帐】蜃校” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵拄养,是天一觀的道長离斩。 經(jīng)常有香客問我银舱,道長,這世上最難降的妖魔是什么跛梗? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任寻馏,我火速辦了婚禮,結(jié)果婚禮上核偿,老公的妹妹穿的比我還像新娘诚欠。我一直安慰自己,他們只是感情好漾岳,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布轰绵。 她就那樣靜靜地躺著,像睡著了一般尼荆。 火紅的嫁衣襯著肌膚如雪左腔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天捅儒,我揣著相機與錄音翔悠,去河邊找鬼。 笑死野芒,一個胖子當(dāng)著我的面吹牛蓄愁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播狞悲,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼撮抓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了摇锋?” 一聲冷哼從身側(cè)響起丹拯,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荸恕,沒想到半個月后乖酬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡融求,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年咬像,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片生宛。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡县昂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出陷舅,到底是詐尸還是另有隱情倒彰,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布莱睁,位于F島的核電站待讳,受9級特大地震影響芒澜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜创淡,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一痴晦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辩昆,春花似錦阅酪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至施无,卻和暖如春辉词,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背猾骡。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工瑞躺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人兴想。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓幢哨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嫂便。 傳聞我的和親對象是個殘疾皇子捞镰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

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

  • 版權(quán)聲明:本文為博主原創(chuàng)文章岸售,未經(jīng)博主允許不得轉(zhuǎn)載。 PS:轉(zhuǎn)載請注明出處作者:TigerChain地址:http...
    TigerChain閱讀 8,379評論 1 9
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,164評論 25 707
  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南厂画,這只是我在學(xué)習(xí)過程中的一些閱讀筆記凸丸,個人覺得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,839評論 1 18
  • 1 React合成事件特點 React自己實現(xiàn)了一套高效的事件注冊袱院,存儲屎慢,分發(fā)和重用邏輯,在DOM事件體系基礎(chǔ)上做...
    Dabao123閱讀 1,737評論 1 1
  • 《蛙》講述了中國近六十年的農(nóng)村生育史坑填,距離80抛人,90年代的人都是遙遠(yuǎn)的。 “計劃生育”成為整個故事的大背景脐瑰,在那個...
    馬以黑閱讀 192評論 1 2