useOutsideClick

googboy·2025년 11월 10일

커스텀훅

목록 보기
1/1

useOutsideClick

돔요소의 바깥쪽을 클릭했을때 콜백함수를 실행하게하는 커스텀 훅

import { useEffect, useRef, useCallback } from "react";

type OutsideClickCallback = () => void;

export const useOutsideClick = () => {
  // 현재 요소와 콜백을 저장
  const elementRef = useRef<HTMLElement | null>(null);
  const callbackRef = useRef<OutsideClickCallback>(() => {});

  useEffect(() => {
    const handleClick = (e: MouseEvent) => {
      const element = elementRef.current;
      if (!element) return;

      if (!element.contains(e.target as Node)) {
        callbackRef.current();
      }
    };

    // 모바일도 고려!
    document.addEventListener("mousedown", handleClick);
    document.addEventListener("touchstart", handleClick, { passive: true });

    return () => {
      document.removeEventListener("mousedown", handleClick);
      document.removeEventListener("touchstart", handleClick);
    };
  }, []);

  // stable한 ref 콜백 - useEvent 패턴 활용
  const stableCallback = useCallback((element: HTMLElement | null) => {
    elementRef.current = element;

    if (!element) return;

    // React 19 cleanup 활용!
    return () => {
      elementRef.current = null;
    };
  }, []);

  // 콜백을 업데이트하고 stable ref를 반환하는 함수
  return (callback: OutsideClickCallback) => {
    callbackRef.current = callback;
    return stableCallback;
  };
};

사용 예시

const onOutsideClick = useOutsideClick();

<div ref={onOutsideClick(() => setIsOpen(false))}>메뉴 내용</div>;

0개의 댓글