[오류 해결] 중첩된 draggable 컴포넌트의 오동작 이슈

Mandy·2024년 1월 3일
0
post-thumbnail

drag가 가능한 대상이 존재할 때, 대상 내부에서도 drag가 가능하게 하려면 어떻게 하면 될까?

가볍게 생각해보면 우선 drag가 가능한 요소를 생성하고 해당 요소의 내부 요소들도 drag가 가능하도록 속성을 부여해주면 될 것으로 생각한다.

그러나 문제가 있다!

만약 drag 해야 하는 대상들이 실시간으로 상태관리 되고 있는 값이라서 drag를 할 때 상태 업데이트가 이루어지도록 설정했는데,

해당 대상의 내부에 있는 draggable한 요소들도 마찬가지라면 어떻게 될까?

보다시피 질문지 박스를 drag 할 때에는 redux action이 updateQuestions로 정상적으로 수행된다.

하지만 내부의 옵션을 drag 해서 옮기면 updateOptions 직후 updateQuestions가 수행되어버린다.

분명히 updateOptions만 수행되도록 했는데 왜 updateQuestions가 수행된 것일까?



바로, 이벤트 전파 때문이다.

그중에서도 특히 이벤트 버블링(Event Bubbling) 에 의해 발생하는 현상이다.

이벤트 버블링이란, 어떤 요소의 이벤트가 발생하고 핸들러를 동작시키면 해당 요소의 부모의 이벤트 핸들러도 동작시키게 되고 조상 요소까지 계속해서 올라가면서 이벤트 핸들러를 동작시키는 현상이다.

거의 모든 이벤트가 버블링되기 때문에 이러한 현상을 겪는 것은 쉬운 일이다.

평상시에는 대부분 이벤트 핸들러를 동작시킬 때 해당 요소의 부모 요소는 이벤트 핸들러가 없다거나 해서 이러한 현상을 마주하지 않았을지도 모른다.

하지만 나의 경우처럼 중첩된 draggable 컴포넌트가 존재한다면 이벤트 버블링을 눈치채고 동작 오류로 인지하게 된다.

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



그렇다면 이 이벤트 버블링 현상을 막고 내가 의도한 대로 통제하려면 어떻게 해야 할까?

답은 참조 링크에서도 확인할 수 있지만, e.stopPropagation() 을 사용하면 되는 것이다.

자식 요소에서 드래그를 마쳤을 때, e.stopPropagation() 을 이용하면 이벤트가 버블링되지 않고 부모 요소의 이벤트 핸들러는 동작하지 않게 된다.


updateOptions에서 updateQuestion으로 이름을 변경했다는 점을 인지하고 확인하면 이전과 달리 내부의 옵션값을 드래그하더라도 updateQuestions가 동작하지 않고 updateQuestion만 동작하게 된다는 사실을 알 수 있다.

즉, 의도한 대로 자식 요소의 드래깅과 부모 요소의 드래깅이 분리된 것이다.

나는 이 방법을 통해서 문제를 해결했지만, 더 효율적이고 좋은 방법이 있다면 수정하는 것도 좋을 것 같다. 이벤트 버블링을 강제로 중단시키는 것이 약간은 찜찜하기 때문이다.




-끝

profile
즐코 행코 하세용

0개의 댓글