React 事件處理與事件傳遞:一篇搞懂冒泡、捕獲與阻止事件!
前言:
在開發React 時,「事件」是我們最常打交道的部分之一。無論是點擊按鈕、提交表單,還是操作其他互動元素,都需要處理事件。如果你剛接觸 React,可能會有以下疑問:
- 為什麼點擊按鈕時會觸發父層的事件?
- 什麼是事件的「冒泡」和「捕獲」?
- 如何攔截事件傳播或避免預設行為?
這篇文章將帶你從零開始理解 React 的事件處理,並解釋事件傳遞的原理及其在開發中的實際應用場景。
React 的事件處理基礎
什麼是事件?
根據 @MDN Web Docs - Introduction to events 對於事件的定義,事件是瀏覽器用來回應用戶操作的一種訊號。例如當你點擊按鈕、鍵入文字、或滑動滑鼠時,瀏覽器都會生成一個事件並傳遞給應用程式進行處理。
常見的事件類型包括:
- 滑鼠事件(Mouse Events):
click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout - 鍵盤事件(Keyboard Events):
keydown,keyup,keypress - 表單事件(Form Events):
submit,change,input,focus,blur
在 JavaScript 中,事件本身是一個由瀏覽器產生的事件物件(Event Object),它記錄了與互動相關的所有資訊,例如觸發的 HTML 元素、滑鼠座標、鍵盤按鍵等。
讓我們看看事件物件的基本樣貌和幾個常用屬性:
document.querySelector('button').addEventListener('click', (event) => {
console.log(event.type); // 事件類型,例如 "click"
console.log(event.target); // 觸發事件的 DOM 元素
console.log(event.currentTarget); // 綁定事件的 DOM 元素
console.log(event.clientX, event.clientY); // 滑鼠的 X、Y 座標
});
HTML/JS 的事件處理方式
在早期的網頁開發中,事件處理主要有以下幾種方式:
-
內聯屬性(Inline Attributes)
直接在 HTML 元素上綁定事件處理邏輯,這種方式直觀但不推薦,因為不易維護。
<button onclick="alert('Hello!')">點擊我</button> -
使用 DOM 的
addEventListener更現代且推薦的方式是使用 JavaScript 的
addEventListener,可以將事件邏輯與 HTML 結構分離,提升可讀性和重用性。const button = document.querySelector('button');
button.addEventListener('click', () => {
alert('Hello!');
});
React 的事件處理方式
React 的事件處理與原生 HTML 有顯著的不同,主要表現在以下幾點:
-
使用合成事件(Synthetic Event)
在 React 中,事件處理是基於一種叫做 合成事件(Synthetic Event) 的機制。合成事件是一層跨瀏覽器的事件封裝,提供了一個一致的介面。React 不會直接將事件綁定到每個 DOM 元素,而是採用事件委派的方式,將所有事件統一綁定到根節點(例如
document或root元素)。這樣做的好處是:
- 跨瀏覽器兼容性:自動處理不同瀏覽器之間的事件差異。
- 效能提升:React 使用事件委派機制,將所有事件綁定在根元素上,減少 DOM 操作。
function handleClick(event) {
console.log(event.type); // "click"
}
<button onClick={handleClick}>點我</button> -
駝峰式命名
在 React 中,事件屬性使用駝峰式命名(Camel Case),例如
onClick、onMouseOver。 -
事件處理程式是函式 引用
React 要求事件處理程式是函式的引用,而不是直接執行結果。這樣可以避免函式在渲染時被過早執行。
錯誤示範:
function handleClick() {
alert('點擊了');
}
<button onClick={handleClick()}>點我</button> // handleClick 立即執行,錯誤!正確寫法:
<button onClick={handleClick}>點我</button>
什麼是事件傳遞?捕獲與冒泡解讀
在 JavaScript 事件模型中,當事件觸發時,並不僅僅作用於目標元素本身,還會按照一個固定的順序傳遞。這種事件傳遞機制分為兩個主要階段:捕獲階段 和 冒泡階段。
事件傳遞的階段
事件在傳遞過程中會經歷以下三個階段:
-
捕獲階段(Capture Phase)
從
window開始,沿著 DOM 樹向下傳遞到事件的目標元素。 -
目標階段(Target Phase)
事件到達目標元素,並執行與該元素相關的事件處理程式。
-
冒泡階段(Bubble Phase)
從目標元素開始,沿著 DOM 樹向上傳遞到
window。
這樣的流程讓開發者可以在事件傳遞的不同階段執行邏輯。