자바스크립트에서는 addEventListener를 사용해서 이벤트를 줄 수 있지만, 반대로 removeEventListener를 사용하면 이벤트를 제거할 수 있다.
프로젝트를 만들면서 menuCategory에 handleClickCategory 이벤트를 줘서 Active되어 있는 class를 제거하고 categoryBackground를 추가함으로써 카테고리를 open하고, categoryBackground영역을 클릭하면 hiddenCategory 함수로 카테고리를 close하는 함수를 만들었다.
const handleClickCategory = () => {
const menuCategory = menuCategoryRef.current;
const categoryBackground = categoryBackgroundRef.current;
menuCategory.classList.remove(styles.categoryActive);
categoryBackground.classList.add(styles.categoryBg);
const hiddenCategory = () => {
menuCategory.classList.add(styles.categoryActive);
categoryBackground.classList.remove(styles.categoryBg);
console.log("카테고리 이벤트");
};
menuCategory.addEventListener("click", hiddenCategory);
categoryBackground.addEventListener("click", hiddenCategory);
};
정상적으로 카테고리가 생겼다가 사라지지만, console창을 보면 이벤트 리스너가 제거되지 않아서 기존의 로그와 같이 계속 출력되는 것을 볼 수 있다.
그래서 hiddenCategory함수 안에 removeEventListener를 줘서 이벤트를 제거해 주었다.
const handleClickCategory = () => {
const menuCategory = menuCategoryRef.current;
const categoryBackground = categoryBackgroundRef.current;
menuCategory.classList.remove(styles.categoryActive);
categoryBackground.classList.add(styles.categoryBg);
const hiddenCategory = () => {
menuCategory.classList.add(styles.categoryActive);
categoryBackground.classList.remove(styles.categoryBg);
// 추가
menuCategory.removeEventListener("click", hiddenCategory);
categoryBackground.removeEventListener("click", hiddenCategory);
console.log("카테고리 이벤트");
};
menuCategory.addEventListener("click", hiddenCategory);
categoryBackground.addEventListener("click", hiddenCategory);
};
console창을 보면 위와 같은 문제가 해결된 것을 확인할 수 있다.
하지만, 비슷한 코드를 반복해서 작성함으로써 보기도 안좋고 코드의 가독성도 떨어지게 된다.
결론,
이벤트를 한번만 실행하려면 addEventListener함수를 사용하여 이벤트를 등록할 때 마지막에 once옵션을 추가해주면 된다.
const handleClickCategory = () => {
const menuCategory = menuCategoryRef.current;
const categoryBackground = categoryBackgroundRef.current;
menuCategory.classList.remove(styles.categoryActive);
categoryBackground.classList.add(styles.categoryBg);
const hiddenCategory = () => {
menuCategory.classList.add(styles.categoryActive);
categoryBackground.classList.remove(styles.categoryBg);
console.log("카테고리 이벤트");
};
// once옵션
menuCategory.addEventListener("click", hiddenCategory, {once: true});
categoryBackground.addEventListener("click", hiddenCategory), {once: true};
};
addEventListener() 메소드의 3번째 파라미터로 { once : true } 인 객체를 전달하였다.
훨씬 깔끔해진 코드를 볼 수 있다.