리액트 onClick이벤트에서 이벤트 버블링 방지하기

Front-end React

이벤트 버블링이란?

이벤트 버블링이란 특정 화면 요소에서 이벤트가 발생했을 때, 해당 이벤트가 더 상위 요소(parent)로 전달되는 특성을 의미한다.

DOM 이벤트 글에 버블링 및 반대 상황인 캡쳐링에 대하여 좀 더 자세하게 설명해두었다.

JSX 코드로는 아래의 예제로 나타낼 수 있다.

const alertForm = (event) => {
  alert(event.target.id + " Form 요소가 클릭되었습니다");
}

const alertDiv = (event) => {
  alert(event.target.id + " Div 요소가 클릭되었습니다");
}

const alertButton = (event) => {
  alert(event.target.id + " Button 요소가 클릭되었습니다");
}

<form onClick={alertForm}>
  <div onClick={alertDiv}>
    <button onClick={alertButton}>
      Click me!
    </button>
  </div>
</form>

위의 구조에서 Click me! 버튼을 클릭하면 button -> div -> form 순서대로 3개의 경고창이 뜨게 된다.

예제

const getWriter = (event) => {
  alert(`${event.target.id} 님이 작성한 글입니다.`)
}

return (
  <>
    {props.data?.fetchPosts.map(el => {
      <PostContainer id={el.writer} onClick={getWriter}> 
        <WriterContainer>
          <Writer>{el.writer}</Writer>
        </WriterContainer>
        <ContentsContainer>{el.contents}</ContentsContainer>
      </PostContainer>
    })}
  </>
)

위 예제에서 ContentsContainer 등 child 컴포넌트를 클릭하게 되면 이벤트 버블링에 의해 PostContaineronClick 이벤트를 실행하게 되는데, 발생한 이벤트에 대한 event.target.id가 없다. 그렇기 때문에 님이 작성한 글입니다 라는 alert 메세지가 뜨게 된다.

이런 상황을 방지하기 위해서는 event.target.id가 아닌 event.currentTarget.id 를 사용하여 버블링을 막아 줄 수 있다.

const getWriter = (event) => {
  alert(`${event.currentTarget.id} 님이 작성한 글입니다.`)
}