Help us understand the problem. What is going on with this article?

Componentの外部をクリックしたら発火するCustom Hooks【React】

概要

Componentの外部をクリックしたときに発火するイベントを管理したい。

コード

Componentの外部をクリックしたら発火するCustom Hooks作りました。

export const useOutsideClickEvent = (
  ref: MutableRefObject<any>,
  onClick: () => void
) => {
  const clickListener = useCallback(
    (e: MouseEvent) => {
      if ((ref?.current as any).contains(e.target)) {
        return;
      }
      onClick();
    },
    [ref.current, onClick]
  );

  useEffect(() => {
    document.addEventListener('click', clickListener);
    return () => {
      document.removeEventListener('click', clickListener);
    };
  }, []);
};

こんな感じで使うと、refで指定されたdivの外部をクリックされたときにsetIsOpen(false)が実行されます。

const Dialog: FC = () => {
    const ref = useRef(null);
    const [isOpen, setIsOpen] = useState<boolean>(false);
    useOutsideClickEvent(ref, () => setIsOpen(false));

    return (
        <div ref={ref}>
            ...
        </div>
    )
}

注意

ClickEventの実行時にrefで指定したDOMの中に要素が入っていないといけないので、動的にコンテンツを書き換える場合は注意が必要です。

if ((ref.current as any).contains(e.target)) {

追記

似たようなのがありました。
https://usehooks.com/useOnClickOutside/

dorarep
いつも困ったときにお世話になっているので、少しでも皆様のお力になれれば幸いです! PHP/Laravel/Ruby on Rails/TypeScript/Vue.js/React/React Native/DevOps/CircleCI/エンジニア採用
https://dorarep.page/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away