Dandy Now!
  • [Next.js] addEventListener로 적용된 클릭 이벤트가 다른 페이지에서도 지속적으로 작동하는 문제@_@
    2023년 11월 13일 08시 59분 43초에 업로드 된 글입니다.
    작성자: DandyNow
    728x90
    반응형

    1. 페이지가 변경되었는데 왜 이전 페이지의 클릭 이벤트가 작동하는 거지???

    Next.js에 mind-ar 라이브러리를 적용해 AR 기능을 구현하고 있다. 이미지를 컴파일한 특정 타깃이 사용자의 단말기(스마트폰 등)에서 스캔되면 3D 모델이 화면에 렌더링 된다. 이 모델에 addEventListener를 이용해 클릭 이벤트를 주었고 잘 동작하였다. 하지만 기대 이상으로 동작한 덕분에 다른 페이지로 이동 후에도 계속 동작하는 문제가 생겼다. 단, 페이지를 새로 고침(F5)하면 클릭 이벤트가 사라진다.

     

    2. addEventListener를 혹시 body에 적용한거임?

    여러 에러들이 그렇지만 막상 해결하고 나면 어디에 말하기도 부끄러운 문제들이 많다. 이번에도 그랬다.  애초에 addEventListener를 body에 적용했었다. Next.js의 돔 트리에서 body는 거의 최상위에 있는 요소이다. body 요소 안에 각종 페이지들이 있다. 따라서 body 요소에 이벤트를 적용했다면 너무나도 당연하게 모든 페이지에 동일한 이벤트가 적용되는 것이다. 그렇기 때문에 새로고침해 body 요소에서 addEventListener 적용이 사라지면 원치 않는 클릭 이벤트가 더 이상 작동하지 않게 되는 것이다. 결국 아래의 코드와 같이 클릭 이벤트가 일어나기를 원했던 페이지의 div 요소에 "arPage"라는 ID 속성을 부여하여 해당 ID 속성을 가진 요소에 클릭 이벤트를 적용하여 문제를 해결할 수 있었다.

    export default function MindAR() {
      useEffect(() => {
        const handleDocumentClick = (e) => {
          // (생략)
        };
    
        // id 속성 값 "arPage"를 가진 div 요소에 "click" 이벤트 적용
        const arPage = document.getElementById("arPage");
        if (arPage) arPage.addEventListener("click", handleDocumentClick);
    
        // (생략)
    
        return () => {
          // (생략)
          // 현재 페이지(컨포넌트)를 벗어날때 id 속성 값 "arPage"를 가진 div 요소에 적용된 "click" 이벤트 제거
          if (arPage) arPage.removeEventListener("click", handleDocumentClick);
        };
      }, []);
    
      return (
        // "click" 이벤트가 적용되는 돔 요소
        <div id="arPage" className={style["ar-container"]} ref={containerRef}></div>
      );
    }

     

    위 코드를 보면 useEffect의 return 부분에 removeEventListener를 통해 컴포넌트가 종료될 때 적용된 "click" 이벤트가 제거하도록 되어있다. body 요소에 적용된 "click" 이벤트도 이때 제거될 거라고 생각했는데 실제로는 그렇지 않았다. 결론적으로 컴포넌트 생명주기에서 컴포넌트가 종료될 때에 removeEventListener로 "click" 이벤트를 제거하도록 하더라도 body 요소에 적용된 경우는 제거되지 않으므로 해당 컴포넌트 내에 있는 돔요소에 addEventListener를 적용해야 한다.

    728x90
    반응형
    댓글