이벤트 위임 ( Vanila JS와 React )

선정·2023년 3월 1일
0

이벤트 위임

여러 개의 하위 DOM 요소에 각각 이벤트 핸들러를 등록하는 대신 하나의 상위 DOM 요소에 이벤트 핸들러를 등록하는 방법

Vanila JS

먼저 이벤트 위임 없이 DOM 요소 각각에 이벤트 핸들러를 등록하는 경우를 보자. <ul> 의 하위 요소인 여러 개의 <li> 요소에 각각 클릭 이벤트에 따른 이벤트 핸들러를 등록한다.

index.html

<nav>
  <ul id="fruits">
    <li id="apple" class="active">Apple</li>
    <li id="banana">Banana</li>
    <li id="peach">Peach</li>
  </ul>
  <div>선택된 과일 : <em class="msg">apple</em></div>
</nav>

style.css

#fruits {
  display: flex;
  list-style-type: none;
  padding: 0;
}
#fruits li {
  width: 100px;
  cursor: pointer;
}
#fruits .active {
  color: red;
  text-decoration: underline;
}

index.js

import './style.css';

const fruits = document.getElementById('fruits');
const msg = document.querySelector('.msg');

function activate({ target }) {
  if (!target.matches('#fruits > li')) return;
  [...fruits.children].forEach((fruit) => {
    fruit.classList.toggle('active', fruit === target);
    msg.textContent = target.id;
  });
}

// 모든 이벤트 타깃에 이벤트 핸들러 등록
document.getElementById('apple').onclick = activate;
document.getElementById('banana').onclick = activate;
document.getElementById('peach').onclick = activate;

위의 예시로는 3개의 <li> 요소가 전부이지만 이벤트 핸들러를 등록해야 하는 요소가 수 십, 수 백개인 경우에는? 해당 DOM 요소마다 이벤트 핸들러를 등록하게 되면 성능 저하를 유발하게 될 것이고 유지 보수 차원에서도 적절하지 않다.

이 때, 이벤트 전파 를 이용해 하나의 상위 DOM 요소에만 이벤트 핸들러를 등록함으로써 이벤트를 위임 하면, 하위 DOM 요소에 일일이 이벤트 핸들러를 등록하지 않아도 하위 요소들의 이벤트를 캐치할 수 있다.

index.js

import './style.css';

const fruits = document.getElementById('fruits');
const msg = document.querySelector('.msg');

function activate({ target }) {
  if (!target.matches('#fruits > li')) return;
  [...fruits.children].forEach((fruit) => {
    fruit.classList.toggle('active', fruit === target);
    msg.textContent = target.id;
  });
}

// 상위 요소(ul#fruits)에 이벤트 위임
document.getElementById('fruits').onclick = activate;

<ul> 요소에 이벤트를 위임한 위의 코드는 <li> 요소에 일일이 이벤트 핸들러를 등록했을 때와 똑같은 기능을 수행해낸다.


React의 이벤트 위임

리액트에서는 이벤트 위임 을 신경써본 적도, 이와 관련해 들어본 적도 없어서 궁금해져서 찾아봤다.

리액트는 자체적으로 모든 이벤트를 이벤트 위임하여 처리하고 있다고 한다. 개발자가 리액트 코드 상에서 이벤트 핸들러를 특정 요소에 등록을 했을 때 vanila JS에서처럼 이벤트 핸들러가 실제 해당 DOM 요소에 붙여지는 것이 아니라, document level로 이벤트를 위임하여 처리된다는 것이다. 편리한 리액트...!

참고
React의 이벤트 위임

profile
starter

0개의 댓글