티스토리 뷰

[TIS] react event의 stopPropagation이 예상한 대로 작동하지 않는다. (React 이벤트 위임, 캡처링과 버블링)

1.문제점

💡
React 컴포넌트에 event를 등록했을때 stopPropagation이 예상한 대로 작동하지 않았다.

테이블 내에서 날짜를 드래그해서 선택되는것은 테이블전체(Container)에

mousedown이벤트가 사용되어 작동한다.

💡
이때 테이블전체(Container)에 등록한mousedown 핸들러의 경우 ref를 활용해 실제 dom에 등록하였다.

즉 이는 날짜를 입력할 수 없는날에도 mousedown이 작동되어 시간이 입력되었다.

이벤트 버블링을 활용하면 문제를 해결할 수 있을것 같아 다음과 같은 계획을 세웠다.

(1) NotAvailableDate컴포넌트에서 mousedown 이벤트를 포착해서

(2) 이벤트 버블링으로 인해 전파되는 이벤트를 stopPropation()을 활용해 막고

(3) 이로인해 Containermousedown이벤트가 전파되지않는 방식으로 문제를 막는다.

그래서 다음과 같이 코드를 작성하였다.

<NotAvailableDate
  onMouseDown={(e) => {
    e.stopPropagation();
  }}
/>

위 방법은 예상했던 것과 달리 위 방법은 작동하지 않았다.

무엇이 문제였을까?

2.원인

💡
React의 컴포넌트에 등록되 이벤트는 root에서 관리한다.
출처: https://reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation

위 이미지에서 보시는 것 처럼

React는 이벤트가 등록된 컴포넌트 대신 실제로는 root에서 해당 이벤트를 위임받고 처리를 한다.

지금 처한 상황을 위처럼 그려보자.

NotAvailableDateonMouseDown을 등록했을때 실제로는 위에 보는것 처럼 해당 이벤트가 위임되어 root에서 관리한다.

이벤트 버블링을 활용하여 해결하려고 했던 내 방법은 잘못된 방법이었다.

3.해결 방안

💡
이벤트 캡처링을 활용하면 해결할 수 있다.

부모 요소를 가지고 있는 요소에서 등록되어 있는 이벤트가 작동할때

브라우저는 아래 그림과 같이 2개의 방향으로 이벤트가 전파된다.

capture phase의 경우 최상단 html부터 시작해 해당 이벤트가 발동한곳까지 이동을 하며 발동한다.

bubble phase의 경우 해당 이벤트가 발동한곳부터 시작해 html까지 이동하며 발동한다.

즉 해당 root에서 mousedown 이벤트를 받아 capture phase에서 전파를 시키지 않으면 된다.

이를 코드로 작성하면 NotAvailableDate에기존에 작성했던 onMouseDown대신 onMouseDownCapture 로 작성하면 된다.

<NotAvailableDate
  onMouseDownCapture={(e) => {
    e.stopPropagation();
  }}
/>

다음과 같이 문제가 해결된 것을 볼 수 있다.

4.이를 통해 배운점

이번에 문제를 해결하면서 React의 컴포넌트에 등록된 이벤트는 root에서 관리하는 것을 알게 되었다.

추가적으로 이벤트 캡처링과 버블링에 대해 다시 한번 집고 넘어갈 수 있어서 좋은 공부가 됬다.

마지막으로 이 글을 통해 react에 등록한 event가 실제 돔에 등록한 이벤트 사이에 문제를 겪는 분들께

도움이 되었으면 좋겠다.

해당 코드는 아래 커밋 기록에서 더 자세하게 확인할 수 있습니다. 감사합니다.

https://github.com/hoon2hooni/time2meet/commit/4c3f5f3e9a85e8805c293b5edf0680b7ba813e00

references

https://ko.javascript.info/bubbling-and-capturing

https://reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation

https://developer.mozilla.org/ko/docs/Learn/JavaScript/Building_blocks/Events


Uploaded by N2T

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함