iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0
Modern Web

重溫 React 官方文件回到最初的起點系列 第 13

Day 13 - 事件傳遞(冒泡與捕捉)

  • 分享至 

  • xImage
  •  

今天的文章接下來繼續介紹最後提到的事件的傳遞,這邊的傳遞通常是指假設我們在 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 (會作為傳入的唯一參數,通常會命名為 eevent),來透過這個 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>
  );
}

試著執行看看就會發現當我們點下按鈕的時候,divalert 就不會執行了。

Event Capturing

另一個跟冒泡相反的從最上層傳遞到最下方的傳遞方式,叫做 事件捕捉(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,他會是我們網站互動的相關的一個非常重要的東西。
今天的文章就到這邊,感謝大家耐心地看完這篇文章,有任何問題與建議歡迎都跟我說,明天見,晚安。


上一篇
Day 12 - 回應 Event
系列文
重溫 React 官方文件回到最初的起點13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言