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

資訊專欄INFORMATION COLUMN

談談React事件機制和未來(react-events)

TNFE / 3418人閱讀

摘要:另外第三方也可以通過的事件插件機制來合成自定義事件,盡管很少人這么做。抽象跨平臺事件機制。打算干預事件的分發(fā)。事件是的一個自定義事件,旨在規(guī)范化表單元素的變動事件。

當我們在組件上設置事件處理器時,React并不會在該DOM元素上直接綁定事件處理器. React內部自定義了一套事件系統(tǒng),在這個系統(tǒng)上統(tǒng)一進行事件訂閱和分發(fā).

具體來講,React利用事件委托機制在Document上統(tǒng)一監(jiān)聽DOM事件,再根據觸發(fā)的target將事件分發(fā)到具體的組件實例。另外上面e是一個合成事件對象(SyntheticEvent), 而不是原始的DOM事件對象.

文章大綱

那為什么要自定義一套事件系統(tǒng)?

基本概念

整體的架構

事件分類與優(yōu)先級

實現(xiàn)細節(jié)

事件是如何綁定的?

事件是如何分發(fā)的?

事件觸發(fā)調度

插件是如何處理事件?

批量執(zhí)行

未來

初探Responder的創(chuàng)建

react-events意義何在?

擴展閱讀

截止本文寫作時,React版本是16.8.6
那為什么要自定義一套事件系統(tǒng)?

如果了解過Preact(筆者之前寫過一篇文章解析Preact的源碼),Preact裁剪了很多React的東西,其中包括事件機制,Preact是直接在DOM元素上進行事件綁定的。

在研究一個事物之前,我首先要問為什么?了解它的動機,才有利于你對它有本質的認識。

React自定義一套事件系統(tǒng)的動機有以下幾個:

1. 抹平瀏覽器之間的兼容性差異。 這是估計最原始的動機,React根據W3C 規(guī)范來定義這些合成事件(SyntheticEvent), 意在抹平瀏覽器之間的差異。

另外React還會試圖通過其他相關事件來模擬一些低版本不兼容的事件, 這才是‘合成’的本來意思吧?。

2. 事件‘合成’, 即事件自定義。事件合成除了處理兼容性問題,還可以用來自定義高級事件,比較典型的是React的onChange事件,它為表單元素定義了統(tǒng)一的值變動事件。另外第三方也可以通過React的事件插件機制來合成自定義事件,盡管很少人這么做。

3. 抽象跨平臺事件機制。 和VirtualDOM的意義差不多,VirtualDOM抽象了跨平臺的渲染方式,那么對應的SyntheticEvent目的也是想提供一個抽象的跨平臺事件機制。

4. React打算做更多優(yōu)化。比如利用事件委托機制,大部分事件最終綁定到了Document,而不是DOM節(jié)點本身. 這樣簡化了DOM事件處理邏輯,減少了內存開銷. 但這也意味著,React需要自己模擬一套事件冒泡的機制

5. React打算干預事件的分發(fā)。v16引入Fiber架構,React為了優(yōu)化用戶的交互體驗,會干預事件的分發(fā)。不同類型的事件有不同的優(yōu)先級,比如高優(yōu)先級的事件可以中斷渲染,讓用戶代碼可以及時響應用戶交互。

Ok, 后面我們會深入了解React的事件實現(xiàn),我會盡量不貼代碼,用流程圖說話。

基本概念 整體的架構

ReactEventListener - 事件處理器. 在這里進行事件處理器的綁定。當DOM觸發(fā)事件時,會從這里開始調度分發(fā)到React組件樹

ReactEventEmitter - 暴露接口給React組件層用于添加事件訂閱

EventPluginHub - 如其名,這是一個‘插件插槽’,負責管理和注冊各種插件。在事件分發(fā)時,調用插件來生成合成事件

Plugin - React事件系統(tǒng)使用了插件機制來管理不同行為的事件。這些插件會處理自己感興趣的事件類型,并生成合成事件對象。目前ReactDOM有以下幾種插件類型:

SimpleEventPlugin - 簡單事件, 處理一些比較通用的事件類型,例如click、input、keyDown、mouseOver、mouseOut、pointerOver、pointerOut

EnterLeaveEventPlugin - mouseEnter/mouseLeave和pointerEnter/pointerLeave這兩類事件比較特殊, 和*over/*leave事件相比, 它們不支持事件冒泡, *enter會給所有進入的元素發(fā)送事件, 行為有點類似于:hover; 而*over在進入元素后,還會冒泡通知其上級. 可以通過這個實例觀察enter和over的區(qū)別.

如果樹層次比較深,大量的mouseenter觸發(fā)可能導致性能問題。另外其不支持冒泡,無法在Document完美的監(jiān)聽和分發(fā), 所以ReactDOM使用*over/*out事件來模擬這些*enter/*leave。

ChangeEventPlugin - change事件是React的一個自定義事件,旨在規(guī)范化表單元素的變動事件。

它支持這些表單元素: input, textarea, select

SelectEventPlugin - 和change事件一樣,React為表單元素規(guī)范化了select(選擇范圍變動)事件,適用于input、textarea、contentEditable元素.

BeforeInputEventPlugin - beforeinput事件以及composition事件處理。

本文主要會關注SimpleEventPlugin的實現(xiàn),有興趣的讀者可以自己閱讀React的源代碼.

EventPropagators 按照DOM事件傳播的兩個階段,遍歷React組件樹,并收集所有組件的事件處理器.

EventBatching 負責批量執(zhí)行事件隊列和事件處理器,處理事件冒泡。

SyntheticEvent 這是‘合成’事件的基類,可以對應DOM的Event對象。只不過React為了減低內存損耗和垃圾回收,使用一個對象池來構建和釋放事件對象, 也就是說SyntheticEvent不能用于異步引用,它在同步執(zhí)行完事件處理器后就會被釋放。

SyntheticEvent也有子類,和DOM具體事件類型一一匹配:

SyntheticAnimationEvent

SyntheticClipboardEvent

SyntheticCompositionEvent

SyntheticDragEvent

SyntheticFocusEvent

SyntheticInputEvent

SyntheticKeyboardEvent

SyntheticMouseEvent

SyntheticPointerEvent

SyntheticTouchEvent

....

事件分類與優(yōu)先級

SimpleEventPlugin將事件類型劃分成了三類, 對應不同的優(yōu)先級(優(yōu)先級由低到高):

DiscreteEvent 離散事件. 例如blur、focus、 click、 submit、 touchStart. 這些事件都是離散觸發(fā)的

UserBlockingEvent 用戶阻塞事件. 例如touchMove、mouseMove、scroll、drag、dragOver等等。這些事件會"阻塞"用戶的交互。

ContinuousEvent 可連續(xù)事件。例如load、error、loadStart、abort、animationEnd. 這個優(yōu)先級最高,也就是說它們應該是立即同步執(zhí)行的,這就是Continuous的意義,即可連續(xù)的執(zhí)行,不被打斷.

可能要先了解一下React調度(Schedule)的優(yōu)先級,才能理解這三種事件類型的區(qū)別。截止到本文寫作時,React有5個優(yōu)先級級別:

Immediate - 這個優(yōu)先級的任務會同步執(zhí)行, 或者說要馬上執(zhí)行且不能中斷

UserBlocking(250ms timeout) 這些任務一般是用戶交互的結果, 需要即時得到反饋 .

Normal (5s timeout) 應對哪些不需要立即感受到的任務,例如網絡請求

Low (10s timeout) 這些任務可以放后,但是最終應該得到執(zhí)行. 例如分析通知

Idle (no timeout) 一些沒有必要做的任務 (e.g. 比如隱藏的內容).

目前ContinuousEvent對應的是Immediate優(yōu)先級; UserBlockingEvent對應的是UserBlocking(需要手動開啟); 而DiscreteEvent對應的也是UserBlocking, 只不過它在執(zhí)行之前,先會執(zhí)行完其他Discrete任務。

本文不會深入React Fiber架構的細節(jié),有興趣的讀者可以閱讀文末的擴展閱讀列表.

實現(xiàn)細節(jié)

現(xiàn)在開始進入文章正題,React是怎么實現(xiàn)事件機制?主要分為兩個部分: 綁定分發(fā).

事件是如何綁定的?

為了避免后面繞暈了,有必要先了解一下React事件機制中的插件協(xié)議。 每個插件的結構如下:

export type EventTypes = {[key: string]: DispatchConfig};

// 插件接口
export type PluginModule = {
  eventTypes: EventTypes,          // 聲明插件支持的事件類型
  extractEvents: (                 // 對事件進行處理,并返回合成事件對象
    topLevelType: TopLevelType,
    targetInst: null | Fiber,
    nativeEvent: NativeEvent,
    nativeEventTarget: EventTarget,
  ) => ?ReactSyntheticEvent,
  tapMoveThreshold?: number,
};

eventTypes聲明該插件負責的事件類型, 它通過DispatchConfig來描述:

export type DispatchConfig = {
  dependencies: Array, // 依賴的原生事件,表示關聯(lián)這些事件的觸發(fā). ‘簡單事件’一般只有一個,復雜事件如onChange會監(jiān)聽多個, 如下圖           
               
                                           
                       
                 

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

轉載請注明本文地址:http://systransis.cn/yun/106354.html

相關文章

  • 一個播放器引發(fā)的思考——談談React跨組件通信

    摘要:如果某個組件訂閱該事件太晚,那發(fā)布者之前所發(fā)布的該類事件,它都接收不到,而方案一和二的優(yōu)點則在于,無論如何,組件都能拿到該的最終狀態(tài)值有存在內存泄漏的風險。 原文地址 - 歡迎關注我的博客 在我們react項目日常開發(fā)中,往往會遇到這樣一個問題:如何去實現(xiàn)跨組件通信? 為了更好的理解此問題,接下來我們通過一個簡單的栗子說明。 實現(xiàn)一個視頻播放器 假設有一個這樣的需求,需要我們去實現(xiàn)一個...

    Dean 評論0 收藏0
  • 一個播放器引發(fā)的思考——談談React跨組件通信

    摘要:如果某個組件訂閱該事件太晚,那發(fā)布者之前所發(fā)布的該類事件,它都接收不到,而方案一和二的優(yōu)點則在于,無論如何,組件都能拿到該的最終狀態(tài)值有存在內存泄漏的風險。 原文地址 - 歡迎關注我的博客 在我們react項目日常開發(fā)中,往往會遇到這樣一個問題:如何去實現(xiàn)跨組件通信? 為了更好的理解此問題,接下來我們通過一個簡單的栗子說明。 實現(xiàn)一個視頻播放器 假設有一個這樣的需求,需要我們去實現(xiàn)一個...

    zhongmeizhi 評論0 收藏0
  • 談談React中Diff算法的策略及實現(xiàn)

    摘要:并且處理特殊屬性,比如事件綁定。之后根據差異對象操作元素位置變動,刪除,添加等。當節(jié)點數過大或者頁面更新次數過多時,頁面卡頓的現(xiàn)象會比較明顯?;谧⒁馐褂脕頊p少組件不必要的更新。 1、什么是Diff算法 傳統(tǒng)Diff:diff算法即差異查找算法;對于Html DOM結構即為tree的差異查找算法;而對于計算兩顆樹的差異時間復雜度為O(n^3),顯然成本太高,React不可能采用這種...

    Scliang 評論0 收藏0
  • 談談React中Diff算法的策略及實現(xiàn)

    摘要:并且處理特殊屬性,比如事件綁定。之后根據差異對象操作元素位置變動,刪除,添加等。當節(jié)點數過大或者頁面更新次數過多時,頁面卡頓的現(xiàn)象會比較明顯?;谧⒁馐褂脕頊p少組件不必要的更新。 1、什么是Diff算法 傳統(tǒng)Diff:diff算法即差異查找算法;對于Html DOM結構即為tree的差異查找算法;而對于計算兩顆樹的差異時間復雜度為O(n^3),顯然成本太高,React不可能采用這種...

    HmyBmny 評論0 收藏0

發(fā)表評論

0條評論

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