亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

react合成事件與原生事件的相關(guān)理解

 更新時(shí)間:2021年05月13日 17:13:47   作者:鑄心  
本文主要介紹了react合成事件與原生事件的相關(guān)概念,幫助大家區(qū)分這兩種事件,學(xué)習(xí)react的同學(xué)不妨了解下

1. 原生事件

原生事件就是js的原生事件,如通過document.addEventListener來設(shè)置的監(jiān)聽事件。

在react中即使有自己的一套事件機(jī)制(見下面合成事件),但有時(shí)候的業(yè)務(wù)場(chǎng)景我們?nèi)匀恍枰褂迷录?。比如我們封裝一個(gè)Modal彈窗組件,需要在點(diǎn)擊非彈窗區(qū)域時(shí)關(guān)掉彈窗,此時(shí)我們只能針對(duì)document進(jìn)行原生點(diǎn)擊事件監(jiān)聽。

由于原生事件需要綁定在真實(shí)DOM上,所以一般是在componentDidMount階段或者組件/元素的ref的函數(shù)執(zhí)行階段進(jìn)行綁定操作,并且注意要在componentWillUnmount階段進(jìn)行解綁操作以避免內(nèi)存泄漏。

2. 合成事件

React有自己的一套事件機(jī)制,它重新封裝了絕大部分的原生事件。合成事件采用了事件池,這樣做可以大大節(jié)省內(nèi)存,而不會(huì)頻繁的創(chuàng)建和銷毀事件對(duì)象。

在React中,如果需要綁定事件,我們常常在jsx中這么寫:

handleClick(){
}
<div onClick={this.handleClick.bind(this)}>
	react事件
</div>

大致原理:

React并不是將click事件綁在該div的真實(shí)DOM上,而是在document處監(jiān)聽所有支持的事件,當(dāng)事件發(fā)生并冒泡至document處時(shí),React將事件內(nèi)容封裝并交由真正的處理函數(shù)運(yùn)行。

以上面的代碼為例,整個(gè)事件生命周期示意如下:

合成事件的一些特點(diǎn)總結(jié):

  • React 上注冊(cè)的事件最終會(huì)綁定在document這個(gè) DOM 上,而不是 React 組件對(duì)應(yīng)的 DOM(減少內(nèi)存開銷就是因?yàn)樗械氖录冀壎ㄔ?document 上,其他節(jié)點(diǎn)沒有綁定事件)
  • React 通過隊(duì)列的形式,從觸發(fā)的組件向父組件回溯,然后調(diào)用他們 JSX 中定義的 callback
  • React 通過對(duì)象池的形式管理合成事件對(duì)象的創(chuàng)建和銷毀,減少了垃圾的生成和新對(duì)象內(nèi)存的分配,提高了性能

了解react合成事件的大概原理后,方便我們解答下面一個(gè)問題:

為什么react事件需要手動(dòng)綁定this

合成事件觸發(fā)之后會(huì)冒泡一路到document的節(jié)點(diǎn),然后開始分發(fā)document節(jié)點(diǎn)收集到的事件,這個(gè)時(shí)候react從事件觸發(fā)的組件實(shí)例開始, 遍歷虛擬dom樹,從樹上取下我們綁定的事件,收集起來,然后執(zhí)行。舉個(gè)例子:

class Test extends React.Component {
   fatherHandler =  function father() { /*...*/}
   childHander = function child() {/*...*/}

   render(){
     return (
       <div onClick={this.fatherHandler}>
         <span onClick={this.childHander}>
         </span>
       </div>
     );
   }

}

當(dāng)事件觸發(fā)以后react會(huì)把上面的事件處理函數(shù)放到一個(gè)數(shù)組里是這樣的

[father, child]

最后,react只要遍歷執(zhí)行這個(gè)數(shù)組,就能執(zhí)行所有需要執(zhí)行的事件處理函數(shù)。這里react對(duì)函數(shù)進(jìn)行了臨時(shí)保存,這個(gè)時(shí)候執(zhí)行的話,this自然就丟失了。

如果react保存順便保存一下實(shí)例,還是可以做到,不需要你綁定this的,但是這樣對(duì)于react來說代價(jià)太大了。

3. 原生與合成事件觸發(fā)順序

  componentDidMount() {
    this.parent.addEventListener('click', (e) => {
      console.log('dom parent');
    })
    this.child.addEventListener('click', (e) => {
      console.log('dom child');
    })
    document.addEventListener('click', (e) => {
      console.log('document');
    })
  }

  childClick = (e) => {
    console.log('react child');
  }

  parentClick = (e) => {
    console.log('react parent');
  }

  render() {
    return (
      <div onClick={this.parentClick} ref={ref => this.parent = ref}>
        <div onClick={this.childClick} ref={ref => this.child = ref}>
          test
        </div>
      </div>)
  }


點(diǎn)擊child中的test后,事件觸發(fā)順序如下:

結(jié)論:

無論是否是對(duì)于同一元素監(jiān)聽的同種類型事件,原生事件總是比合成事件先觸發(fā)。這是由于上面我們說到的合成事件最終都會(huì)綁定到documnet DOM上導(dǎo)致的,當(dāng)合成事件監(jiān)聽到后,總是冒泡到document才會(huì)真正觸發(fā)。 而documnet DOM上監(jiān)聽的原生事件則總是最后觸發(fā)

4. 合成事件和原生事件混用

react合成事件和原生事件最好不要混用。

原生事件中如果執(zhí)行了stopPropagation(阻止冒泡)方法,則很容易導(dǎo)致其他同類型react合成事件失效。因?yàn)檫@樣所有同級(jí)以及后代元素的合成事件和原生事件都將無法冒泡到document上。

而如果僅僅是合成事件中使用了e.stopPropagation(阻止冒泡)方法,則不會(huì)影響原生事件的冒泡

相關(guān)疑問:

我們知道React事件監(jiān)聽器中獲得的入?yún)⒉⒉皇菫g覽器原生事件,原生事件可以通過e.nativeEvent來獲取。通過這種方式,合成事件可以影響原生事件嗎?

e.nativeEvent.stopPropagation

即使在react的合成事件中調(diào)用原生事件的阻止冒泡,實(shí)際作用是在DOM最外層阻止冒泡,并不符合預(yù)期。也就是說它最終只能控制當(dāng)前監(jiān)聽的合成事件不會(huì)冒泡到document DOM的原生事件

e.nativeEvent.stopImmediatePropagation

該方法與上面的nativeEvent.stopPropagation有類似的功能,都可阻止當(dāng)前監(jiān)聽的合成事件冒泡到document DOM的原生事件

stopImmediatePropagation常常在多個(gè)第三方庫(kù)混用時(shí),用來阻止多個(gè)事件監(jiān)聽器中的非必要執(zhí)行。比如同一個(gè)元素的同種事件,設(shè)置了多個(gè)監(jiān)聽事件函數(shù),則該方式可以控制監(jiān)聽函數(shù)只觸發(fā)第一個(gè)

stopImmediatePropagation和stopPropagation本都是原生事件,但在React自己的事件體系中,重新封裝了后者,卻沒有封裝前者。導(dǎo)致在合成事件中只能手動(dòng)調(diào)用nativeEvent.stopImmediatePropagation。

因?yàn)樵赗eact的合成事件機(jī)制中,一個(gè)組件只能綁定一個(gè)同類型的事件監(jiān)聽器(重復(fù)定義時(shí),后面的監(jiān)聽器會(huì)覆蓋之前的),所以合成事件無需去封裝stopImmediatePropagation。

所以,在React的合成事件中,e.nativeEvent.stopPropagation和e.nativeEvent.stopImmediatePropagation實(shí)際的作用是等價(jià)的

此外,由于事件綁定的順序問題,需要注意,如果是在react-dom.js加載前綁定的document原生事件,stopImmediatePropagation也是無法阻止的。

以上就是react合成事件與原生事件的相關(guān)理解的詳細(xì)內(nèi)容,更多關(guān)于react合成事件與原生事件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React拆分窗格組件的兩種方法

    React拆分窗格組件的兩種方法

    這篇文章主要介紹了React拆分窗格組件的兩種方法,使用第三方庫(kù)react-split-pane適用于快速實(shí)現(xiàn)拆分窗格功能,并且對(duì)功能和樣式的要求較為簡(jiǎn)單的場(chǎng)景,本文結(jié)合示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • 在React項(xiàng)目中實(shí)現(xiàn)一個(gè)簡(jiǎn)單的錨點(diǎn)目錄定位

    在React項(xiàng)目中實(shí)現(xiàn)一個(gè)簡(jiǎn)單的錨點(diǎn)目錄定位

    錨點(diǎn)目錄定位功能在長(zhǎng)頁(yè)面和文檔類網(wǎng)站中非常常見,它可以讓用戶快速定位到頁(yè)面中的某個(gè)章節(jié),本文講給大家介紹一下React項(xiàng)目中如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的錨點(diǎn)目錄定位,文中有詳細(xì)的實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2023-09-09
  • 基于React實(shí)現(xiàn)搜索GitHub用戶功能

    基于React實(shí)現(xiàn)搜索GitHub用戶功能

    在本篇博客中,我們將介紹如何在 React 應(yīng)用中搜索 GitHub 用戶并顯示他們的信息,文中通過代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • 詳解在React項(xiàng)目中如何集成和使用web worker

    詳解在React項(xiàng)目中如何集成和使用web worker

    在復(fù)雜的React應(yīng)用中,某些計(jì)算密集型或耗時(shí)操作可能會(huì)阻塞主線程,導(dǎo)致用戶界面出現(xiàn)卡頓或響應(yīng)慢的現(xiàn)象,為了優(yōu)化用戶體驗(yàn),可以采用Web Worker來在后臺(tái)線程中執(zhí)行這些操作,本文將詳細(xì)介紹在React項(xiàng)目中如何集成和使用Web Worker來改善應(yīng)用性能,需要的朋友可以參考下
    2023-12-12
  • create-react-app修改為多頁(yè)面支持的方法

    create-react-app修改為多頁(yè)面支持的方法

    本篇文章主要介紹了create-react-app修改為多頁(yè)面支持的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • react-diagram 序列化Json解讀案例分析

    react-diagram 序列化Json解讀案例分析

    今天帶來大家學(xué)習(xí)react-diagram 序列化Json解讀的相關(guān)知識(shí),本文通過多種案例給大家分析序列化知識(shí),通過圖文并茂的形式給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2021-05-05
  • react優(yōu)雅處理多條件鼠標(biāo)拖拽位移

    react優(yōu)雅處理多條件鼠標(biāo)拖拽位移

    這篇文章主要為大家詳細(xì)介紹了react優(yōu)雅處理多條件鼠標(biāo)拖拽位移,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • react 組件表格固定底部的實(shí)現(xiàn)代碼

    react 組件表格固定底部的實(shí)現(xiàn)代碼

    在React中,要實(shí)現(xiàn)一個(gè)組件表格并且固定底部,可以使用CSS的固定定位或絕對(duì)定位來實(shí)現(xiàn),下面通過示例代碼給大家分享react 組件表格固定底部的實(shí)現(xiàn)代碼,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • 基于React路由跳轉(zhuǎn)的幾種方式

    基于React路由跳轉(zhuǎn)的幾種方式

    這篇文章主要介紹了React路由跳轉(zhuǎn)的幾種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • react 項(xiàng)目中引入圖片的幾種方式

    react 項(xiàng)目中引入圖片的幾種方式

    本文主要介紹了react 項(xiàng)目中引入圖片,本文詳細(xì)的介紹了幾種方法,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06

最新評(píng)論