一幅慌、合成事件
react 基于 vitrual dom 實(shí)現(xiàn)了 syntheticEvent (合成事件)芦倒,react 事件處理器接收到一個(gè) syntheticEvent 對(duì)象蛤织,syntheticEvent 和原生瀏覽器事件一樣擁有同樣的接口赴叹,也支持事件冒泡機(jī)制≈秆粒可以通過 stopPropgation 和 preventDefault? 中斷乞巧。如果需要訪問原生事件對(duì)象,可以使用 nativeEvent 屬性摊鸡。
二绽媒、實(shí)現(xiàn)機(jī)制
react 的事件機(jī)制利用了事件委托機(jī)制。事件并沒有綁定在真實(shí)的 dom 節(jié)點(diǎn)上免猾,而是把事件都綁定在結(jié)構(gòu)的最外層 document是辕,使用一個(gè)統(tǒng)一的事件監(jiān)聽器。所有的事件都由這個(gè)監(jiān)聽器統(tǒng)一分發(fā)猎提。
組件掛載和更新時(shí)获三,會(huì)將綁定的事件分門別類的放進(jìn)一個(gè)叫做EventPluginHub的事件池里。事件觸發(fā)時(shí),根據(jù)事件產(chǎn)生的Event對(duì)象找到觸發(fā)事件的組件疙教,再通過組件標(biāo)識(shí)和事件類型從事件池里找到對(duì)應(yīng)的事件監(jiān)聽回調(diào)棺聊,然后執(zhí)行相關(guān)的監(jiān)聽函數(shù)。
三贞谓、react 中怎么使用原生
在 didmount 中限佩,也可以對(duì)真實(shí)的 dom 節(jié)點(diǎn),進(jìn)行原生的事件綁定裸弦,原生事件的綁定要在 unmount 時(shí)進(jìn)行解綁祟同,以防止內(nèi)存泄漏
但?syntheticEvent 的 stopPropgation 無法阻止原生事件的冒泡。反之原生事件的阻止冒泡行為理疙,卻可以阻止合成事件的傳播耐亏。所以盡量不要原生與合成事件混用,如必須混用沪斟,又無法阻止冒泡广辰,使用 e.target 進(jìn)行判斷。
四主之、異步回調(diào)怎么使用?syntheticEvent
React追求極致的性能择吊。在合成事件機(jī)制里,一旦事件監(jiān)聽回調(diào)被執(zhí)行槽奕,合成事件對(duì)象就會(huì)被銷毀几睛,異步的回調(diào)執(zhí)行的時(shí)候合成事件對(duì)象早就被銷毀了。解決方法粤攒,就是執(zhí)行下面的 event.persist(); 用于通知 react 不需要回收所森,
五、與原生對(duì)比
由于原生的捕獲機(jī)制并不常用夯接,且具有 ie 的不兼容問題焕济, react 僅實(shí)現(xiàn)了冒泡機(jī)制。既沒有兼容問題盔几,而且使用委托機(jī)制只有 document 節(jié)點(diǎn)上才有 DOM 事件也節(jié)約了內(nèi)存晴弃。
六、事件執(zhí)行
找到事件觸發(fā)的 DOM 和 React Component逊拍,從該 React Component上鞠,調(diào)用 findParent 方法,遍歷得到所有父組件芯丧,存在數(shù)組中芍阎。從該組件直到最后一個(gè)父組件,根據(jù)之前事件存儲(chǔ)缨恒,用 React 事件名 + 組件 key谴咸,找到對(duì)應(yīng)綁定回調(diào)方法度硝。