2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Reactでハンバーガーメニューの実装(外部ライブラリ無し)

Posted at

どうもこんにちは、たくびー(@takubii)です。

今回はReactでハンバーガーメニューの実装を行ったので備忘録として記事にしたいと思います。
昨今だとライブラリなどであるかもしれませんが、今回はライブラリを使わずReactの機能とWeb標準のみで実装しています。

簡単に説明

ロジックが多いですが、少し凝ったことをしていて、アニメーションが始まった時にサイドバーが出現し、終わった時に消えるようにしています。
サイドバー展開中はコンテンツにオーバーレイを被せることでコンテンツへのクリックを制限しています。
また、オーバーレイ自体に触るとサイドバーが消えるようになっているので少しユーザーフレンドリーかなと思います。

実装

アイコンはBootstrap Iconを使用しています。

jsx
export const App = () => {
  const [menuOpen, setMenuOpen] = useState(false);
  const toggleMenu = () => {
    const sidebar = document.querySelector('.sidebar');
    if (!menuOpen) {
      sidebar.style.display = 'block';
      setTimeout(() => {
        setMenuOpen(true);
      }, 10);
    } else {
      setMenuOpen(false);
    }
  }
  const closeMenu = () => {
    setMenuOpen(false);
  }

  useEffect(() => {
    const sidebar = document.querySelector('.sidebar');
    const handleTransitionEnd = () => {
      if (!menuOpen) {
        sidebar.style.display = 'none';
      }
    };
    sidebar.addEventListener('transitionend', handleTransitionEnd);

    return () => {
      sidebar.removeEventListener('transitionend', handleTransitionEnd);
    };
  }, [menuOpen]);

  <div className='header'>
    <div className='hamburger-menu' onClick={toggleMenu}>
      <i className='bi bi-list'></i>
    </div>
  </div>

  {menuOpen && <div className='overlay' onClick={closeMenu}></div>}

  <div className={`sidebar ${menuOpen ? 'open' : ''}`} style={{ display: 'none' }}>
    <div className='hamburger-menu-close' onClick={toggleMenu}>
      <i className='bi bi-x-lg'></i>
    </div>
    <p>test1</p>
    <p>test2</p>
    <p>test3</p>
  </div>

  <div className='contents'>
  </div>
}
css
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  z-index: 999;
}

.sidebar {
  position: fixed;
  top: 0;
  width: 250px;
  height: 100%;
  background: white;
  transform: translateX(-100%);
  transition: transform 0.3s ease-in-out;
  z-index: 1000;
}

.sidebar.open {
  transform: translateX(0);
}

.sidebar .hamburger-menu-close {
  display: inline-block;
}

終わりに

横から出てくるタイプのハンバーガーメニューはいろいろな場所で目にしますが、実際に実装してみると結構手間がかかるなと思いました。
車輪の再発明になっているかもしれませんが、もし実装で困っている方の助けになれば幸いです。

それでは今回はこのあたりで締めたいと思います。
ここまで読んでいただきありがとうございます。
また機会があればお会いしましょう。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?