react的合成事件如何形容

2022-12-15 22:00:30

React合成事件是React模擬原生DOM事件所有能力的一個事件物件,即瀏覽器原生事件的跨瀏覽器包裝器;它根據W3C規範來定義合成事件,相容所有瀏覽器,擁有與瀏覽器原生事件相同的介面。在React中,所有事件都是合成的,不是原生DOM事件,但可以通過「e.nativeEvent」屬性獲取DOM事件。

前端(vue)入門到精通課程,老師線上輔導:聯絡老師
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API偵錯工具:

本教學操作環境:Windows7系統、react18版、Dell G3電腦。

一、合成事件是什麼

React基於瀏覽器的事件機制自身實現了一套事件機制,包括事件註冊、事件的合成、事件冒泡、事件派發等

在React中這套事件機制被稱之為合成事件

合成事件(SyntheticEvent)

React 合成事件(SyntheticEvent)是 React 模擬原生 DOM 事件所有能力的一個事件物件,即瀏覽器原生事件的跨瀏覽器包裝器。它根據 W3C 規範 來定義合成事件,相容所有瀏覽器,擁有與瀏覽器原生事件相同的介面。例如

const button = <button onClick={handleClick}>按鈕</button>
登入後複製

在 React 中,所有事件都是合成的,不是原生 DOM 事件,但可以通過 e.nativeEvent 屬性獲取 DOM 事件。 比如:

const handleClick = (e) => console.log(e.nativeEvent);;
const button = <button onClick={handleClick}>按鈕</button>
登入後複製

從上面可以看到React事件和原生事件也非常的相似,但也有一定的區別:

  • 事件名稱命名方式不同

// 原生事件繫結方式
<button onclick="handleClick()">按鈕命名</button>
      
// React 合成事件繫結方式
const button = <button onClick={handleClick}>按鈕命名</button>
登入後複製
  • 事件處理常式書寫不同

// 原生事件 事件處理常式寫法
<button onclick="handleClick()">按鈕命名</button>
      
// React 合成事件 事件處理常式寫法
const button = <button onClick={handleClick}>按鈕命名</button>
登入後複製

雖然onclick看似繫結到DOM元素上,但實際並不會把事件代理函數直接繫結到真實的節點上,而是把所有的事件繫結到結構的最外層,使用一個統一的事件去監聽。【相關推薦:Redis視訊教學、】

這個事件監聽器上維持了一個對映來儲存所有元件內部的事件監聽和處理常式。當元件掛載或解除安裝時,只是在這個統一的事件監聽器上插入或刪除一些物件。

當事件發生時,首先被這個統一的事件監聽器處理,然後在對映裡找到真正的事件處理常式並呼叫。這樣做簡化了事件處理和回收機制,效率也有很大提升。

二、執行順序

關於React合成事件與原生事件執行順序,可以看看下面一個例子:

import  React  from 'react';
class App extends React.Component{

  constructor(props) {
    super(props);
    this.parentRef = React.createRef();
    this.childRef = React.createRef();
  }
  componentDidMount() {
    console.log("React componentDidMount!");
    this.parentRef.current?.addEventListener("click", () => {
      console.log("原生事件:父元素 DOM 事件監聽!");
    });
    this.childRef.current?.addEventListener("click", () => {
      console.log("原生事件:子元素 DOM 事件監聽!");
    });
    document.addEventListener("click", (e) => {
      console.log("原生事件:document DOM 事件監聽!");
    });
  }
  parentClickFun = () => {
    console.log("React 事件:父元素事件監聽!");
  };
  childClickFun = () => {
    console.log("React 事件:子元素事件監聽!");
  };
  render() {
    return (
      <div ref={this.parentRef} onClick={this.parentClickFun}>
        <div ref={this.childRef} onClick={this.childClickFun}>
          分析事件執行順序
        </div>
      </div>
    );
  }
}
export default App;
登入後複製

輸出順序為:

原生事件:子元素 DOM 事件監聽! 
原生事件:父元素 DOM 事件監聽! 
React 事件:子元素事件監聽! 
React 事件:父元素事件監聽! 
原生事件:document DOM 事件監聽!
登入後複製

可以得出以下結論:

  • React 所有事件都掛載在 document 物件上

  • 當真實 DOM 元素觸發事件,會冒泡到 document 物件後,再處理 React 事件

  • 所以會先執行原生事件,然後處理 React 事件

  • 最後真正執行 document 上掛載的事件

對應過程如圖所示:

1.jpg

所以想要阻止不同時間段的冒泡行為,對應使用不同的方法,對應如下:

  • 阻止合成事件間的冒泡,用e.stopPropagation()

  • 阻止合成事件與最外層 document 上的事件間的冒泡,用e.nativeEvent.stopImmediatePropagation()

  • 阻止合成事件與除最外層document上的原生事件上的冒泡,通過判斷e.target來避免

document.body.addEventListener('click', e => {   
    if (e.target && e.target.matches('div.code')) {  
        return;    
    }    
    this.setState({   active: false,    });   }); 
}
登入後複製

三、總結

React事件機制總結如下:

  • React 上註冊的事件最終會繫結在document這個 DOM 上,而不是 React 元件對應的 DOM(減少記憶體開銷就是因為所有的事件都繫結在 document 上,其他節點沒有繫結事件)

  • React 自身實現了一套事件冒泡機制,所以這也就是為什麼我們 event.stopPropagation()無效的原因。

  • React 通過佇列的形式,從觸發的元件向父元件回溯,然後呼叫他們 JSX 中定義的 callback

  • React 有一套自己的合成事件 SyntheticEvent

(學習視訊分享:)

以上就是react的合成事件如何形容的詳細內容,更多請關注TW511.COM其它相關文章!