[Trend-Now] ref와 document 이벤트를 이용한 외부 클릭 감지 구현하기

강수영·2025년 6월 25일
0

1. 문제 상황

검색창에 자동완성 기능을 추가하던 중, 입력 후 자동완성 리스트가 계속 열린 상태로 유지되는 문제가 있었습니다.

사용자가 입력창 외부를 클릭하면 자동완성 리스트가 자연스럽게 닫혀야 하기 때문에 외부 클릭을 감지하는 로직이 필요했습니다.

2. 외부 클릭 감지 구현하기

외부 클릭 감지를 구현하기 위해서는 refdocument.addEventListener가 필요합니다.

ref는 특정 DOM 요소에 직접 접근하기 위해 사용되며, document.addEventListener는 문서 전체에서 발생하는 클릭 이벤트를 감지하기 위해 사용됩니다.

const [isOpen, setIsOpen] = useState(false);
const wrapperRef = useRef<HTMLDivElement>(null);

useEffect(() => {
  const handleClickOutside = (e: MouseEvent) => {
	  // ref로 참조한 요소가 존재하고,
	  // 클릭된 요소(e.target)가 그 요소 내부(wrapperRef.current)에 포함되어 있지 않은 경우
    if (wrapperRef.current && !wrapperRef.current.contains(e.target as Node)) {
      setIsOpen(false); // 외부 클릭 시 자동완성 닫기
    }
  };
  
	// 문서 전체에서 마우스 클릭이 발생했을 때 handleClickOutside 함수가 실행되도록 이벤트를 등록
  document.addEventListener('mousedown', handleClickOutside);
  return () => {
	  // 등록한 mousedown 이벤트 리스너를 제거해, 컴포넌트가 사라질 때 불필요한 이벤트 호출을 방지
    document.removeEventListener('mousedown', handleClickOutside);
  };
}, []);

위 코드는 ref로 감싼 컴포넌트 외부를 클릭했을 때 자동완성 UI를 닫는 로직입니다.

  • ref를 통해 기준 영역을 지정하고,
  • document의 전역 클릭 이벤트를 통해 외부 클릭 여부를 감지하며,
  • 컴포넌트가 언마운트될 때 이벤트를 제거해 메모리 누수를 방지합니다.

그리고 input에 포커스가 될 때 setIsOpen(true)를 호출하면, 자동완성 UI를 입력 전에 미리 열어줄 수도 있습니다.

profile
프론트엔드 개발자

0개의 댓글