훅(Hook)

useClickOutside - 외부 클릭 닫기 훅

드롭다운·팝오버·모달의 외부 mousedown/touchstart를 감지해 자동으로 닫는 훅

ReactTypeScriptTailwind CSS
라이브 데모
새 탭에서 열기
데모 불러오는 중…

제작 과정

드롭다운/팝오버 UX의 90%는 "패널 외부 어디든 클릭하면 닫힌다"는 한 가지 약속에서 옵니다. 직접 구현하려면 document에 mousedown 리스너를 달고, 이벤트 타깃이 ref가 가리키는 요소 안에 있는지 Node.contains로 검사한 뒤 핸들러를 호출해야 합니다. 이 훅은 그 과정을 한 줄로 줄입니다: const ref = useClickOutside(() = setOpen(false)). handler를 ref로 감싸서 stale closure 문제도 막고, enabled 옵션으로 패널이 닫혀있을 땐 리스너 자체를 떼어 불필요한 비용도 없앴습니다. 모바일 호환을 위해 mousedown과 touchstart를 함께 잡습니다.

데모에서는 같은 페이지에 독립 드롭다운 3개가 있고, 각자 자신의 ref만 검사하기 때문에 한 메뉴를 열어둔 채 다른 메뉴 트리거를 누르면 자연스럽게 첫 번째가 닫히고 두 번째가 열립니다. 외부 회색 영역도 외부로 인식돼 모두 닫힙니다.

소스 코드

· 데모 페이지에서 자동 추출
import type { Metadata } from "next";
import { UseClickOutsideDemo } from "./-components/UseClickOutsideDemo";

export const metadata: Metadata = {
  title: "useClickOutside — 외부 클릭 닫기 훅 (데모)",
  description: "ref 외부 mousedown/touchstart를 감지해 드롭다운·팝오버를 닫는 useClickOutside 훅의 라이브 시연.",
  robots: { index: false, follow: false },
};

export default function Page() {
  return (
    <main className="min-h-[100dvh] bg-white flex items-center justify-center">
      <UseClickOutsideDemo />
    </main>
  );
}
29조회수

댓글