合成事件
如果DOM上綁定了過多的事件處理函數,整個頁面響應以及內存佔用可能都會受到影響。React爲了避免這類DOM事件濫用,同時屏蔽底層不同瀏覽器之間的事件系統差異,實現了一箇中間層——SyntheticEvent。
步驟
react事件機制執行分爲如下兩個步驟。
- 事件綁定:當用戶在爲onClick添加函數時,React並沒有將Click時間綁定在DOM上面。而是在document處監聽所有支持的事件,
- 事件觸發:當事件發生並冒泡至document處時,使用統一的分發函數dispatchEvent將指定函數執行。
特點
- 幾乎所有的事件代理(delegate)到
document
,達到性能優化的目的。(注意⚠️:對於audio、video標籤,存在一些媒體事件(例如onplay、onpause),而這些事件是document不具有的,那麼只能在這些標籤上進行事件綁定,綁定一個入口分發函數(dispatchEvent)) - 對於每種類型的事件,擁有統一的分發函數
dispatchEvent
- 事件對象(event)是合成對象(SyntheticEvent),不是原生的
合成事件和原生事件的區別
- 寫法不同,在原生事件中,事件名稱使用小寫,而 React 中使用駝峯命名。如果採用 JSX 的語法你需要傳入一個函數作爲事件處理函數,而不是一個字符串(DOM 元素的寫法)
// 原生事件 <button onclick="buttonClick()"> // React事件 <button onClick="buttonClick()">
- 阻止默認行爲不同,在 HTML 中,阻止事件的默認行爲使用 return false,而 React 中必須調用 preventDefault。
// 原生 <button onclick="console.log('123'); return false"> // React function buttonClick(e) { e.preventDefault() }
- 機制不同,原生是直接將事件綁定到當前元素,React 中的事件機制則分爲兩個階段:事件註冊、事件分發。所有的事件都會註冊到 document 上,當觸發時,會採用事件冒泡的形式冒泡到document上面,然後React將事件封裝給正式的函數處理運行和處理。
代碼分析:http://zhenhua-lee.github.io/react/react-event.html