문제 및 배경
할 일을 띄웠을 때에만, 제거하는 버튼을 보여주는 UX를 주고 싶었다.
그러나 고민이 있었다.
만약 버튼이 100만 개가 생겼다면, 하나하나에 이벤트를 다는 것은 꽤나 번거로운 방식이다.
또한,
MouseOver
과 MouseLeave
을 둘 다 달아야 하는 것 역시 번거로운 작업이었다.따라서 나는 다른 방향으로 문제를 접근하고, 해결하고 싶었다.
힌트
toggle
메서드를 이용하자
DOMTokenList.toggle()
를 이용하면 어떨까 싶었다.먼저
toggle
의 경우, 2번째 인자까지 받을 수 있다.2번째 인자를 입력하면, 해당 조건에 맞는 경우에만 토글될 수 있도록 하는 것이다.
이벤트 위임을 활용하자
이벤트 위임을 활용하면 각각에 이벤트를 달지 않아도 충분히 전체적으로 제어할 수 있다.
따라서
closest
를 활용하여 더욱 효과적으로 문제를 해결하고자 했다.실제 코드
Sidebar
return 부분
<TagList onMouseOver={handleTagItemHover}> {tags.map((tag) => ( <TagItem key={tag} onClick={handleTagItemClick}> <TagItemTodo>{tag}</TagItemTodo> <TagItemRemove>X</TagItemRemove> </TagItem> ))} </TagList>
handleTagItemHover
간단하다.
- 부모 요소 중
li
가 있으면 갖고 오고, 아니면 리턴한다.
- 그럼 이제 버튼이 있을 것인데
- 현재
currentTarget
에서의 리스트 버튼들과 만약 다르다면 토글을 꺼주고, 아니면 토글을 해주는 방식으로 구현한다.
const handleTagItemHover = (e) => { const closestLi = e.target.closest('li'); if (!closestLi) return; const activeButton = closestLi.querySelector('button'); e.currentTarget.querySelectorAll('li > button').forEach((buttonElement) => { buttonElement.classList.toggle('active', buttonElement === activeButton); }); };

해결을 완료했다!