React Hooks で作る要素の外側をクリックすると閉じるドロップダウン


はじめに

こんにちは。親から送られてくる家庭菜園の動画に癒されている kimizuy です。

今回は要素の外側をクリックすると閉じるドロップダウンのコンポーネントを React Hooks で実装した例を紹介します。

紹介するコンポーネントは以下のような動きになります。

  • 「Toggle dropdown」を押すとドロップダウン(メニューリスト)を表示する
  • ドロップダウンの外側をクリックするとドロップダウンが閉じる

Codesandbox のデモも用意しました。実際に触って試してみてください。

tldr

さっそくドロップダウンコンポーネントの実装例を紹介します。

useState でドロップダウンの表示・非表示の状態を管理しています。また useRef でドロップダウンの要素を参照し、useEffect で要素外のクリックを検知することでメニューを閉じられるようにしました。

function Dropdown() {
  const [showDropdown, setShowDropdown] = useState(false);
  const dropdownListRef = useRef<HTMLUListElement>(null);

  useEffect(() => {
    const handleClickToCloseDropdown = (event: any) => {
      const element = dropdownListRef.current;
      if (!showDropdown || element?.contains(event.target)) return;
      setShowDropdown(false);
    };

    window.addEventListener("click", handleClickToCloseDropdown);
    return () => {
      window.removeEventListener("click", handleClickToCloseDropdown);
    };
  }, [showDropdown, dropdownListRef]);

  return (
    <div className="DropdownContainer">
      <button
        type="button"
        onClick={() => {
          setShowDropdown((prevState) => !prevState);
        }}
      >
        Toggle dropdown
      </button>

      {showDropdown && (
        <ul ref={dropdownListRef} className="DropdownList">
          <li className="Item">
            <button onClick={() => console.log("item 1 clicked!")}>
              item 1
            </button>
          </li>
          <li className="Item">
            <button onClick={() => console.log("item 2 clicked!")}>
              item 2
            </button>
          </li>
        </ul>
      )}
    </div>
  );
}

おわりに

今回は React Hooks でドロップダウンコンポーネントを実装してみました。このテクニックは任意の要素の外側や内側のクリックイベントなどを検知して何かの処理を実行したくなったときに応用できそうですね。

以上、お読みいただきありがとうございました。

Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています

弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?

もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!

求人応募してみる!

投稿者 Gaji-Labo Staff

Gaji-Laboの社内デジタル環境でいろいろなお手伝いをしているがじ専務&じら常務。みんなのシリーズ記事をまとめたり、卒業したスタッフの過去記事を記録したり、Twitterをやったりしています。