React基础之事件机制
?
某次被問到?React事件機制的問題,關于這一塊我確實不怎么清楚,因為平時大部分工作都是用?Vue,對于?React的熟悉程度只限于會
Vue通過編譯模板,解析出事件指令,將事件和事件回調附加到?vnode tree上,在?patch過程中的創(chuàng)建階段和更新階段都會對這個?vnode tree進行處理,拿到每個?vnode上附加的事件信息,就可以調用原生?DOM API對相應事件進行注冊或移除,流程還是比較清晰的,而React則是單獨實現了一套事件機制
在?react源碼的?react-dom/src/events/ReactBrowserEventEmitter.js文件的開頭,看了一些源碼和一些注釋太多了也沒有仔細研究,然后從網上也是總結了別人的一些總結如下
?1.React事件使用了事件委托的機制,一般事件委托的作用都是為了減少頁面的注冊事件數量,減少內存開銷,優(yōu)化瀏覽器性能,React這么做也是有這么一個目的,除此之外,也是為了能夠更好的管理事件,實際上,React中所有的事件最后都是被委托到了 document這個頂級DOM上
2.既然所有的事件都被委托到了 document上,那么肯定有一套管理機制,所有的事件都是以一種先進先出的隊列方式進行觸發(fā)與回調
3.既然都已經接管事件了,那么不對事件做些額外的事情未免有些浪費,于是 React中就存在了自己的 合成事件(SyntheticEvent),合成事件由對應的 EventPlugin負責合成,不同類型的事件由不同的 plugin合成,例如 SimpleEvent Plugin、TapEvent Plugin等
4.為了進一步提升事件的性能,使用了 EventPluginHub這個東西來負責合成事件對象的創(chuàng)建和銷毀
?
這里也是有三個面試相關的題,和答案
一、組件基礎
1. React 事件機制
<div onClick={this.handleClick.bind(this)}>點我</div>
React并不是將click事件綁定到了div的真實DOM上,而是在document處監(jiān)聽了所有的事件,當事件發(fā)生并且冒泡到document處的時候,React將事件內容封裝并交由真正的處理函數運行。這樣的方式不僅僅減少了內存的消耗,還能在組件掛在銷毀時統一訂閱和移除事件。
? JSX 上寫的事件并沒有綁定在對應的真實 DOM 上,而是通過事件代理的方式,將所有的事件都統一綁定在了?document?上。這樣的方式不僅減少了內存消耗,還能在組件掛載銷毀時統一訂閱和移除事件。
另外冒泡到?document?上的事件也不是原生瀏覽器事件,而是 React 自己實現的合成事件(SyntheticEvent)。因此我們如果不想要事件冒泡的話,調用?event.stopPropagation?是無效的,而應該調用?event.preventDefault。
實現合成事件的目的如下:
合成事件首先抹平了瀏覽器之間的兼容問題,另外這是一個跨瀏覽器原生事件包裝器,賦予了跨瀏覽器開發(fā)的能力;
對于原生瀏覽器事件來說,瀏覽器會給監(jiān)聽器創(chuàng)建一個事件對象。如果你有很多的事件監(jiān)聽,那么就需要分配很多的事件對象,造成高額的內存分配問題。但是對于合成事件來說,有一個事件池專門來管理它們的創(chuàng)建和銷毀,當事件需要被使用時,就會從池子中復用對象,事件回調結束后,就會銷毀事件對象上的屬性,從而便于下次復用事件對象。
二, React的事件和普通的HTML事件有什么不同?
區(qū)別:
對于事件名稱命名方式,原生事件為全小寫,react 事件采用小駝峰;
對于事件函數處理語法,原生事件為字符串,react 事件為函數;
react 事件不能采用 return false 的方式來阻止瀏覽器的默認行為,而必須要地明確地調用preventDefault()來阻止默認行為。
合成事件是 react 模擬原生 DOM 事件所有能力的一個事件對象,其優(yōu)點如下:
?
兼容所有瀏覽器,更好的跨平臺;
將事件統一存放在一個數組,避免頻繁的新增與刪除(垃圾回收)。
方便 react 統一管理和事務機制。
事件的執(zhí)行順序為原生事件先執(zhí)行,合成事件后執(zhí)行,合成事件會冒泡綁定到 document 上,所以盡量避免原生事件與合成事件混用,如果原生事件阻止冒泡,可能會導致合成事件不執(zhí)行,因為需要冒泡到document 上合成事件才會執(zhí)行。
?
3. React 組件中怎么做事件代理?它的原理是什么?
React基于Virtual DOM實現了一個SyntheticEvent層(合成事件層),定義的事件處理器會接收到一個合成事件對象的實例,它符合W3C標準,且與原生的瀏覽器事件擁有同樣的接口,支持冒泡機制,所有的事件都自動綁定在最外層上。
在React底層,主要對合成事件做了兩件事:
事件委派:?React會把所有的事件綁定到結構的最外層,使用統一的事件監(jiān)聽器,這個事件監(jiān)聽器上維持了一個映射來保存所有組件內部事件監(jiān)聽和處理函數。
自動綁定:?React組件中,每個方法的上下文都會指向該組件的實例,即自動綁定this為當前組件。
?
總結
- 統一的分發(fā)函數dispatchEvent。
- React的事件對象是合成對象(SyntheticEvent)。
- 幾乎所有的事件都委托到document,達到性能優(yōu)化的目的。
- 合成事件與原生事件混用要注意React的事件基本都是委托到document。
最后給大家奉上源碼解析的文章鏈接
https://juejin.cn/post/6844903700423507976?share_token=296b0c62-98f7-4b5f-9ccd-316b6fb59067
?
總結
以上是生活随笔為你收集整理的React基础之事件机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: intel945显卡linux驱动,下载
- 下一篇: dropbear:一个小巧的ssh se