본문 바로가기
Insights/Troubleshooting

[동네zip] React 모달창 버튼 클릭 오류, 알고 보니 이벤트 버블링?! 🫧

by suyeonnie 2025. 3. 5.

이론으로만 접했던 이벤트 버블링 문제를 실제 프로젝트에서 처음 경험했다.
처음 CORS 에러를 마주했을 때처럼, '네가 말로만 듣던 걔구나! ㅋㅋㅋ'싶어서 순간 반가운(?) 마음이 들기도 했다.

문제 상황

중고 거래 물품 목록 페이지

 
 
중고 거래 물품 목록 페이지에서 비로그인 사용자가 '찜(하트 아이콘)'을 클릭했을 때, 로그인 모달을 띄우는 기능을 구현했다.
그런데 모달 내 `[로그인하기]`  `[닫기]` 버튼을 클릭해도 의도와 다르게 [물품 상세 페이지]로 이동하는 현상이 발생함 🚨
 
상황을 요약하면 다음과 같다.

  • `ProductCard`에는 클릭 시 상세 페이지로 이동하는 이벤트가 등록되어 있음
  • `ModalLogin` 컴포넌트 내 버튼 클릭 시 이벤트가 부모 요소인 `ProductCard`까지 전파되면서 이동 이벤트까지 실행됨
  • 따라서 모달 내 버튼 클릭 시에도 상세 페이지로 이동하는 문제가 발생함

 

원인 분석: 이벤트 버블링

 
 
이벤트 버블링은 하위 요소 → 상위 요소로 이벤트가 전파되는 현상이다.
기본적으로 브라우저는 이미지와 같이 `캡처링 → 타겟 → 버블링` 순으로 이벤트를 처리한다.
 
이번 케이스는 하위 요소(모달 버튼)을 클릭했는데, 상위 요소(ProductCard)의 이벤트가 실행된 상황이다.
 

문제 상황 : 이벤트 버블링

 

문제 상황 : 이벤트 버블링

 
 
 

해결 방법: 이벤트 전파 차단

 
버블링으로 인한 이벤트 전파를 막기 위해 `e.stopPropagation()`을 사용했다.
이 함수는 현재 이벤트가 상위 요소로 전달되지 않도록 막아준다.
 
[모달창]

<ModalOverlay onClick={onClose}>
  <ModalContent onClick={(e) => e.stopPropagation()}>
    <Button
      onClick={(e) => {
        e.stopPropagation(); // 이벤트 전파 방지
        onNavigate();        // 로그인 페이지로 이동
      }}
    >
      로그인하기
    </Button>
    <Button
      onClick={(e) => {
        e.stopPropagation(); // 이벤트 전파 방지
        onClose();           // 모달 닫기
      }}
    >
      닫기
    </Button>
  </ModalContent>
</ModalOverlay>

 

  • ModalContent와 모달 내부 버튼 (`로그인하기`, `닫기`) 모두 이벤트 전파를 차단하도록 설정
  • 외부 영역 클릭 시 모달이 닫히도록 `ModalOverlay`에 `onClick={onClose}` 설정

 

이벤트 전파 제어 정리

이벤트 전파 중지하기!

 
 
이벤트 동작을 제어하는 함수 :

함수 개념
e.stopPropagation() 부모 요소로 이벤트 전파 중단
e.preventDefault() 이벤트 기본 동작 막기 (ex. <a> 링크 이동 차단), 이벤트 전파는 막지 않음
e.stopImmediatePropagation() 같은 이벤트에 등록된 다른 이벤트 리스너의 실행 막기
e.currentTarget 이벤트가 실제로 이벤트 리스너가 부착된 요소를 참조함

 
이번 문제는 부모 요소로의 전파를 막는 게 핵심이므로 `e.stopPropagation()`을 사용하는 것이 적절했다.
 

결과

결과

 
모달창 버튼 클릭 시 이벤트가 상위로 전달되지 않도록 차단하여, [물품 상세 페이지]로 이동하는 문제가 해결되었다.
의도한 대로 로그인 모달이 작동하고, 사용자 경험이 개선되었다.
 

회고

컴포넌트 중첩 구조에서의 이벤트 흐름 제어의 중요성을 깨달았다.
특히 모달처럼 부모-자식 관계가 명확한 UI에서는 이벤트 전파 관리를 유의해야한다.
 
이번 경험을 통해 컴포넌트 분리와 이벤트 위임에 대한 고민이 더 깊어졌다 🥲
 
 

참고

[MDN Web Docs] 이벤트 버블링
[모던 JS 튜토리얼] 버블링과 캡처링
[Inpa Dev] 한눈에 이해하는 이벤트 흐름 제어(버블링 & 캡처링)
[캡틴판교] 이벤트 버블링, 이벤트 캡처 그리고 이벤트 위임까지