1. 程式人生 > >react虛擬事件(合成事件)與dom原生事件的混用

react虛擬事件(合成事件)與dom原生事件的混用

react合成事件

如果DOM上綁定了過多的事件處理函式,整個頁面響應以及記憶體佔用可能都會受到影響。React為了避免這類DOM事件濫用,同時遮蔽底層不同瀏覽器之間的事件系統差異,實現了一箇中間層——SyntheticEvent。

原理

React中,如果需要繫結事件,我們常常在jsx中這麼寫:

<div onClick={this.onClick}>
    react事件
</div>

原理大致如下:

React並不是將click事件綁在該div的真實DOM上,而是在document處監聽所有支援的事件,當事件發生並冒泡至document處時,React將事件內容封裝並交由真正的處理函式執行。

以上面的程式碼為例,整個事件生命週期示意如下:

其中,由於event物件是複用的,事件處理函式執行完後,屬性會被清空,所以event的屬性無法被非同步訪問,詳情請查閱event-pooling


事件響應順序

由於原生事件需要繫結在真實DOM上,所以一般是在componentDidMount階段/ref的函式執行階段進行繫結操作,在componentWillUnmount階段進行解綁操作以避免記憶體洩漏。

示例如下:

class Demo extends React.PureComponent {
    componentDidMount() {
        const $this = ReactDOM.findDOMNode(this
) $this.addEventListener('click', this.onDOMClick, false) } onDOMClick = evt => { // ... } render() { return ( <div>Demo</div> ) } }
小結:

1.首先DOM事件監聽器被執行,然後事件繼續冒泡至document,合成事件監聽器再被執行。
2.合成事件的捕獲階段響應也晚於原生事件的冒泡階段響應

其實是因為,合成事件的代理並不是在document上同時註冊捕獲/冒泡階段的事件監聽器的,事實上只有冒泡階段的事件監聽器,每一次DOM事件的觸發,React會在event._dispatchListeners

上注入所有需要執行的函式,然後依次迴圈執行(如上文React原始碼)


作者:Nekron
連結:https://juejin.im/post/59db6e7af265da431f4a02ef
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

作者:Nekron
連結:https://juejin.im/post/59db6e7af265da431f4a02ef
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
作者:Nekron
連結:https://juejin.im/post/59db6e7af265da431f4a02ef
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。