今天的文章接下來繼續介紹最後提到的事件的傳遞,這邊的傳遞通常是指假設我們在 Component 裡,觸發的事件可能會根據 Parent 跟 Child 的不同而有不同層的事件執行。直接拿文章中的例子當範例,當用 div
包住 button
的時候,並且讓兩個 JSX tag 都傳入 onClick
handler。在點擊 button
的時候,同時也是在點擊 div
,這樣執行的順序會如何呢?
export default function Toolbar() {
return (
<div className="Toolbar" onClick={() => {
alert('You clicked on the toolbar!');
}}>
<button onClick={() => alert('Playing!')}>
Play Movie
</button>
<button onClick={() => alert('Uploading!')}>
Upload Image
</button>
</div>
);
}
實際操作就會發現他會先顯示我們的按的按鈕的 alert
像是如果我們按 Play Movie,就會先顯示 Playing!,之後再顯示 You clicked on the toolbar!,而如果我們不按兩個按鈕,直接按 div
範圍內的區域,就會只顯示 You clicked on the toolbar!。如此可知,事件會從觸發的 Child 先執行,再慢慢往他的 Parent 去執行,這樣往上傳也稱為 事件冒泡(Event Bubbling)。
但有時候我們會只想觸發當前的 UI 的互動事件,像是範例中的按鈕,這時候就會用到在 handler
會接收的 Event Object (會作為傳入的唯一參數,通常會命名為 e
或 event
),來透過這個 object 來獲得事件資訊。這個 Event Object 的用途很多,其中一個就是可以來停止事件的傳遞,會用到 object 裡的 stopPropagation
方法。實際操作就會像是在 handler
裡加入 e.stopPropagation()
來執行:
export default function Toolbar() {
return (
<div className="Toolbar" onClick={() => {
alert('You clicked on the toolbar!');
}}>
<button onClick={(event) => {
event.stopPropagation()
alert('Playing')
}}>
Play Movie
</button>
<button onClick={(event) => {
event.stopPropagation()
alert('Uploading!')
}}>
Upload Image
</button>
</div>
);
}
試著執行看看就會發現當我們點下按鈕的時候,div
的 alert
就不會執行了。
另一個跟冒泡相反的從最上層傳遞到最下方的傳遞方式,叫做 事件捕捉(Event Capturing)
如果想在 React 裡面執行 Capturing,就要在想進行捕捉的 Parent tag 上的 onClick
加上 Capture
變成 onClickCapture
,這樣就會在同時點擊的時候優先從 Parent 開始觸發。拿文章中的範例就會變成:
export default function Toolbar() {
return (
<div className="Toolbar" onClickCapture={() => {
alert('You clicked on the toolbar!');
}}>
<button onClick={(event) => {
event.stopPropagation()
alert('Playing')
}}>
Play Movie
</button>
<button onClick={(event) => {
event.stopPropagation()
alert('Uploading!')
}}>
Upload Image
</button>
</div>
);
}
更改後再點擊按鈕就會發現會先執行 You clicked on the toolbar! 再執行點擊按鈕的 alert
訊息,然後因為變成 Capturing,stopProgagation
就在這邊不會生效(由下往上的過程被 stop,但改成捕捉變成由上往下)
在前面提到我們要阻止傳遞會需要用到 event object 裡的 stopPropagation
,而這個 object 還有另一個功能,就是能阻止一些事件的預設行為。最常見的就是 <form>
裡的 onSubmit
。在預設的情況下,我們點擊提交(submit)按鈕,會讓頁面重整,而如果我們想阻止這個預設行為,就可以使用 event.preventDefault()
來避免掉。
Event object 還有其他常用的資訊,在之後的篇章也會再更多詳細的介紹。
今天介紹了事件在 Parent 跟 Child 是怎麼傳遞的,以及冒泡跟捕捉的差別。並且也稍微提到了 Event Object 的運用,接下來下一步會再來介紹另一個 React 的核心: State,他會是我們網站互動的相關的一個非常重要的東西。
今天的文章就到這邊,感謝大家耐心地看完這篇文章,有任何問題與建議歡迎都跟我說,明天見,晚安。