独自のuseOnOutsideClickフックを使用してドロップダウンメニューを閉じる方法は?

1
2022.01.14

私は私のモバイルdrowdownメニューに問題に直面しました。私は私のボタンとドロップダウン項目の外側(どこか、上記のタイテルで言いましょう)をクリックしてドロップダウンを閉じたいと思います。

これは私の です。

メニュー

const Menu = () => {
  const [isMobileNavOpen, setMobileNavState] = useState(false);

  const mobileNavRef = useRef();

  useOnOutsideClick(mobileNavRef, () => {
    if (isMobileNavOpen) setMobileNavState(false);
  });

  const toggleMobileNav = () => {
    setMobileNavState(!isMobileNavOpen);
  };

  return (
    <div>
      <div className="dropdown" ref={mobileNavRef}>
        <button
          className="dropdown-btn"
          onClick={toggleMobileNav}
          type="button"
        >
          DROPDOWN BUTTON
        </button>
        {isMobileNavOpen && (
          <div
            className="dropdown-menu"
            onClick={() => setMobileNavState(false)}
          >
            <a className="dropdown-item" href="#">
              Item1
            </a>
            <a className="dropdown-item" href="#">
              Item2
            </a>
          </div>
        )}
      </div>
    </div>
  );
};

私のフックの使用オンクリック外部

export const useOnOutsideClick = (ref, callback) => {
  const handleClick = (e) => {
    if (ref.current && ref.current.contains(e.target)) {
      callback();
      console.log("click");
    }
  };

  useEffect(() => {
    document.addEventListener("click", handleClick);

    return () => {
      document.removeEventListener("click", handleClick);
    };
  });
};

どんな助けについてお願いします!

回答
3
2022.01.14

useOutsideClickフックのロジックを反転します。参照がアタッチされているターゲット要素内に含まれていないクリック イベントをチェックする。

const handleClick = (e) => {
  if (!ref.current?.contains(e.target)) {
    callback();
    console.log("click");
  }
};

Edit how-to-close-dropdown-menu-using-own-useonoutsideclick-hook

フック全体

export const useOnOutsideClick = (ref, callback) => {
  const handleClick = (e) => {
    if (!ref.current?.contains(e.target)) {
      callback();
      console.log("click");
    }
  };

  useEffect(() => {
    document.addEventListener("click", handleClick);

    return () => {
      document.removeEventListener("click", handleClick);
    };
  });
};