[TIL] 이벤트 버블링, 이벤트 캡쳐링, 해결 방법
        
        
      Created By: 성희 배 Last Edited: Apr 24, 2020 6:58 PM Tags: cs

호텔 클로닝 사이드 프로젝트에서 발생한 문제이다.
자식 버튼을 누를 시에 부모의 이벤트가 호출되는 현상이 나타났다. 문제는 이벤트 버블링 때문이었다.
이벤트 버블링
- 하위 엘리먼트에 이벤트 발생 시 그 엘리먼트부터 상위 요소까지 이벤트가 전달되는 방식
 

- 위와 같은 형식이 있을 때, 
li를 클릭하게 되면li→ul→div순으로 호출된다. 
이벤트 캡쳐링
- 하위 엘리먼트에 이벤트 핸들러가 있을 때 상위 엘리먼트부터 이벤트가 발생 해 하위 엘리먼트까지 이벤트가 전달됨
 

- 똑같은 형식에 
li를 클릭 시ul을 호출하고 싶을때,ul의 이벤트 리스너에{capture : true}로 우선순위를 부여할 수 있다. 
이벤트 위임 (참고)
조상에 이벤트를 등록하여 조상이 하위 element에 이벤트를 위임하는 방식.
PROS
- element의 공통 조상에만 핸들러를 달면 하위 element들에도 적용할 수 있다. → 메모리 절약
    
- ex) 테이블의 경우 
<table>에 핸들러를 달고,e.target으로 구별 후 작업 
 - ex) 테이블의 경우 
 - element가 추가 되어도 부모가 핸들링 하기 때문에 각각 리스너를 부여할 필요가 없다. → 코드가 짧아진다.
 
CONS
- 이벤트가 반드시 버블링 되어야 한다.
 
버블링 해결
- 
    
그래서 버블링을 해결하기 위해 어떻게 해야할까? 몇 가지 방법이 있다.
###
event.preventDefault();- 브라우저 동작은 막아주지만 (href 같은 것) 이벤트가 DOM에서 bubbling 되는 건 막지 못한다.
 
###
event.stopPropagation();- 이벤트가 DOM에서 bubbling 되는 건 막지만, 브라우저 동작은 막지 못한다.
 
###
return false;- JQuery 코드에서 많이 쓰이고, 브라우저 동작과 이벤트 버블링을 막고 어떤 콜백에서든 즉시 return한다.
 
 
const handleErrorBtnClicked = (e) =>{
        e.stopPropagation();
        if(retryCnt >= 3) {
            setError(true)
            return;
        }
        setRetryCnt(retryCnt+1);
        refetch();
    }
- bubbling되어서 부모의 onclick에 접근하였기 때문에, 버블링을 막기 위해 
event.stopPropagation()을 리스너 상단에 추가 해 주었다. 

이제 retry 버튼을 클릭 하여도 부모 이벤트가 실행되지 않는다!
It works! :)
참고
How to correctly use preventDefault(), stopPropagation(), or return false; on events