🚫

[react]初心者: イベント伝播 stopPropagation() vs preventDefault()

2024/01/31に公開

vueなら@click.stopでやってくれているので何も考えてないが
reactはonClick.stop={handleClick}なんてできないから雰囲気でe.preventDefault()入れてみたものの親へイベント伝播してしまって改めて調べてみた
頭がvue製だったのでreactを使うことでjsのことちゃんと考えるようになるかも

伝播してしまう例

reactのコンポーネントで、下記のような場合、IconButtonをクリックしたらhandleClickActionsが発火し、そのあとにhandleCoverClickedも発火してしまいます。

<li onClick={handleItemClicked}>
  <IconButton onClick={handleActionsClicked}>
    <MoreVertIcon />
  </IconButton>
</li>
const handleItemClicked = (
  e: React.MouseEvent<HTMLLIElement>,
) => {
console.log('handleItemClicked')
}

const handleActionsClicked = (
  event: React.MouseEvent<HTMLButtonElement>,
) => {
  event.preventDefault()
  console.log('handleActionsClicked')
}

伝播しない例

handleActionsClickedのイベントが親要素に伝播しないためには、event.preventDefault()ではなくevent.stopPropagation()

const handleItemClicked = (
  e: React.MouseEvent<HTMLLIElement>,
) => {
console.log('handleItemClicked')
}

const handleActionsClicked = (
  event: React.MouseEvent<HTMLButtonElement>,
) => {
  e.stopPropagation()
  console.log('handleActionsClicked')
}

stopPropagationpreventDefault

event.preventDefault()event.stopPropagation()は、JavaScriptでのイベント処理において異なる役割を果たす

event.preventDefault()

イベントによって通常実行されるブラウザのデフォルトアクションをキャンセルする。
たとえば、フォームの送信ボタンをクリックした際に、event.preventDefault()を呼び出すと、フォームがサーバーに送信されるのを防ぐことができる。
たとえば、リンクがクリックされた際には、新しいページへの移動を防ぐことができる。
このメソッドは、イベントの伝播(イベントがDOMツリー上で親要素に伝わること)には影響しない!というか関係ない!(恥)

→ 「このイベントが通常行うべきことをしないでください」という命令

event.stopPropagation()
イベントの伝播を停止する。つまり、現在の要素で発生したイベントが、親要素や祖先要素へと伝わるのを防ぎぐ
イベントバブリングやイベントキャプチャリングのプロセスに影響し、親要素のイベントハンドラが呼び出されるのを防ぎますが、イベント自体のデフォルトの動作(たとえばリンクのクリックによるページ遷移など)には影響しない

→ 「このイベントをここで止めて、それ以上親に伝えないでください」という命令

以上

Discussion