DEV Community

William Baker
William Baker

Posted on

Advanced Slide-Out Menus with react-burger-menu in React

react-burger-menu is a powerful library for creating animated slide-out navigation menus in React applications. It provides multiple animation styles, customizable positioning, and advanced features for building sophisticated mobile and desktop navigation experiences. This guide walks through advanced usage of react-burger-menu with React, including custom configurations, multiple menu styles, and complex navigation patterns. This is part 42 of a series on using react-burger-menu with React.

Prerequisites

Before you begin, make sure you have:

  • Node.js version 14.0 or higher installed
  • npm, yarn, or pnpm package manager
  • A React project (version 16.8 or higher) or create-react-app setup
  • Basic knowledge of React hooks (useState, useEffect)
  • Familiarity with JavaScript/TypeScript
  • Understanding of CSS for styling and animations

Installation

Install react-burger-menu using your preferred package manager:

npm install react-burger-menu
Enter fullscreen mode Exit fullscreen mode

Or with yarn:

yarn add react-burger-menu
Enter fullscreen mode Exit fullscreen mode

Or with pnpm:

pnpm add react-burger-menu
Enter fullscreen mode Exit fullscreen mode

After installation, your package.json should include:

{
  "dependencies": {
    "react-burger-menu": "^3.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Project Setup

react-burger-menu requires CSS imports for styling. Import the styles in your main entry file:

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import 'react-burger-menu/lib/styles.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

First Example / Basic Usage

Let's create a simple slide-out menu. Create a new file src/BurgerMenuExample.jsx:

// src/BurgerMenuExample.jsx
import React, { useState } from 'react';
import { slide as Menu } from 'react-burger-menu';

function BurgerMenuExample() {
  const [isOpen, setOpen] = useState(false);

  const handleStateChange = (state) => {
    setOpen(state.isOpen);
  };

  const closeMenu = () => {
    setOpen(false);
  };

  return (
    <div>
      <Menu
        isOpen={isOpen}
        onStateChange={handleStateChange}
        width={280}
        right
      >
        <a id="home" className="menu-item" href="/" onClick={closeMenu}>
          Home
        </a>
        <a id="about" className="menu-item" href="/about" onClick={closeMenu}>
          About
        </a>
        <a id="contact" className="menu-item" href="/contact" onClick={closeMenu}>
          Contact
        </a>
      </Menu>
      <div style={{ padding: '20px' }}>
        <h2>Main Content</h2>
        <p>Click the hamburger icon to open the menu.</p>
      </div>
    </div>
  );
}

export default BurgerMenuExample;
Enter fullscreen mode Exit fullscreen mode

Update your App.jsx:

// src/App.jsx
import React from 'react';
import BurgerMenuExample from './BurgerMenuExample';
import './App.css';

function App() {
  return (
    <div className="App">
      <BurgerMenuExample />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Understanding the Basics

react-burger-menu provides several animation styles:

  • slide: Slides in from the side
  • stack: Stacks menu items
  • elastic: Elastic animation effect
  • bubble: Bubble animation
  • push: Pushes content aside
  • rotate: Rotates while opening
  • scaleDown: Scales down while opening
  • scaleRotate: Combines scale and rotate
  • fallDown: Falls down from top
  • reveal: Reveals menu behind content

Key concepts for advanced usage:

  • Menu Components: Import different animation styles as components
  • State Management: Control menu open/close state with isOpen prop
  • Event Handlers: Use onStateChange to track menu state changes
  • Positioning: Control menu position with left or right props
  • Customization: Extensive styling and behavior customization options

Here's an example with different animation styles:

// src/AnimationStylesExample.jsx
import React, { useState } from 'react';
import { slide, stack, elastic, bubble } from 'react-burger-menu';

function AnimationStylesExample() {
  const [isOpen, setOpen] = useState(false);
  const [menuStyle, setMenuStyle] = useState('slide');

  const MenuComponent = {
    slide,
    stack,
    elastic,
    bubble
  }[menuStyle] || slide;

  const menuItems = [
    { id: 'home', label: 'Home', href: '#home' },
    { id: 'about', label: 'About', href: '#about' },
    { id: 'services', label: 'Services', href: '#services' },
    { id: 'contact', label: 'Contact', href: '#contact' }
  ];

  return (
    <div>
      <div style={{ padding: '20px', backgroundColor: '#f0f0f0' }}>
        <h2>Menu Animation Styles</h2>
        <div style={{ marginBottom: '20px' }}>
          <label>Select Style: </label>
          <select
            value={menuStyle}
            onChange={(e) => {
              setMenuStyle(e.target.value);
              setOpen(false);
            }}
            style={{ padding: '5px', marginLeft: '10px' }}
          >
            <option value="slide">Slide</option>
            <option value="stack">Stack</option>
            <option value="elastic">Elastic</option>
            <option value="bubble">Bubble</option>
          </select>
        </div>
      </div>
      <MenuComponent
        isOpen={isOpen}
        onStateChange={(state) => setOpen(state.isOpen)}
        width={280}
        right
      >
        {menuItems.map(item => (
          <a
            key={item.id}
            id={item.id}
            className="menu-item"
            href={item.href}
            onClick={() => setOpen(false)}
          >
            {item.label}
          </a>
        ))}
      </MenuComponent>
      <div style={{ padding: '20px' }}>
        <button
          onClick={() => setOpen(!isOpen)}
          style={{
            padding: '10px 20px',
            backgroundColor: '#007bff',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: 'pointer'
          }}
        >
          Toggle Menu
        </button>
      </div>
    </div>
  );
}

export default AnimationStylesExample;
Enter fullscreen mode Exit fullscreen mode

Practical Example / Building Something Real

Let's build a comprehensive navigation system with multiple menu styles and advanced features:

// src/AdvancedNavigation.jsx
import React, { useState, useEffect } from 'react';
import { slide, stack, elastic } from 'react-burger-menu';

function AdvancedNavigation() {
  const [isOpen, setOpen] = useState(false);
  const [menuStyle, setMenuStyle] = useState('slide');
  const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);

  useEffect(() => {
    const handleResize = () => {
      setIsMobile(window.innerWidth <= 768);
      if (window.innerWidth > 768) {
        setOpen(false);
      }
    };

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  const MenuComponent = {
    slide,
    stack,
    elastic
  }[menuStyle] || slide;

  const menuItems = [
    { id: 'home', label: 'Home', href: '#home', icon: '🏠' },
    { id: 'about', label: 'About', href: '#about', icon: 'ℹ️' },
    { id: 'services', label: 'Services', href: '#services', icon: 'βš™οΈ' },
    { id: 'portfolio', label: 'Portfolio', href: '#portfolio', icon: 'πŸ“' },
    { id: 'blog', label: 'Blog', href: '#blog', icon: 'πŸ“' },
    { id: 'contact', label: 'Contact', href: '#contact', icon: 'πŸ“§' }
  ];

  const handleStateChange = (state) => {
    setOpen(state.isOpen);
  };

  const closeMenu = () => {
    setOpen(false);
  };

  return (
    <div style={{ minHeight: '100vh' }}>
      {/* Mobile Menu */}
      {isMobile && (
        <MenuComponent
          isOpen={isOpen}
          onStateChange={handleStateChange}
          width={300}
          right
          customBurgerIcon={false}
          customCrossIcon={false}
          styles={{
            bmMenu: {
              background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
              padding: '2.5em 1.5em 0',
              fontSize: '1.15em'
            },
            bmItemList: {
              color: '#b8b7ad',
              padding: '0.8em'
            },
            bmItem: {
              display: 'block',
              color: 'white',
              textDecoration: 'none',
              padding: '15px',
              marginBottom: '10px',
              borderRadius: '8px',
              transition: 'background-color 0.3s'
            },
            bmOverlay: {
              background: 'rgba(0, 0, 0, 0.3)'
            }
          }}
        >
          <div style={{
            color: 'white',
            fontSize: '24px',
            fontWeight: 'bold',
            marginBottom: '30px',
            paddingBottom: '20px',
            borderBottom: '2px solid rgba(255, 255, 255, 0.3)'
          }}>
            Navigation
          </div>
          {menuItems.map(item => (
            <a
              key={item.id}
              id={item.id}
              className="menu-item"
              href={item.href}
              onClick={closeMenu}
              style={{
                display: 'flex',
                alignItems: 'center',
                gap: '15px',
                color: 'white',
                textDecoration: 'none',
                padding: '15px',
                marginBottom: '10px',
                borderRadius: '8px',
                transition: 'background-color 0.3s'
              }}
              onMouseEnter={(e) => e.target.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'}
              onMouseLeave={(e) => e.target.style.backgroundColor = 'transparent'}
            >
              <span style={{ fontSize: '20px' }}>{item.icon}</span>
              <span>{item.label}</span>
            </a>
          ))}
        </MenuComponent>
      )}

      {/* Desktop Navigation */}
      {!isMobile && (
        <nav style={{
          backgroundColor: '#2c3e50',
          padding: '15px 30px',
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
        }}>
          <div style={{ color: 'white', fontSize: '24px', fontWeight: 'bold' }}>
            MyApp
          </div>
          <div style={{ display: 'flex', gap: '30px' }}>
            {menuItems.map(item => (
              <a
                key={item.id}
                href={item.href}
                style={{
                  color: 'white',
                  textDecoration: 'none',
                  padding: '8px 15px',
                  borderRadius: '4px',
                  transition: 'background-color 0.3s'
                }}
                onMouseEnter={(e) => e.target.style.backgroundColor = '#34495e'}
                onMouseLeave={(e) => e.target.style.backgroundColor = 'transparent'}
              >
                {item.label}
              </a>
            ))}
          </div>
        </nav>
      )}

      {/* Main Content */}
      <div style={{ padding: '40px' }}>
        <h1>Welcome to My App</h1>
        <p>This is the main content area.</p>
        {isMobile && (
          <button
            onClick={() => setOpen(!isOpen)}
            style={{
              marginTop: '20px',
              padding: '10px 20px',
              backgroundColor: '#007bff',
              color: 'white',
              border: 'none',
              borderRadius: '4px',
              cursor: 'pointer'
            }}
          >
            {isOpen ? 'Close Menu' : 'Open Menu'}
          </button>
        )}
      </div>
    </div>
  );
}

export default AdvancedNavigation;
Enter fullscreen mode Exit fullscreen mode

Add custom styles in App.css:

/* src/App.css */
.menu-item {
  display: block;
  color: white;
  text-decoration: none;
  padding: 15px;
  margin-bottom: 10px;
  border-radius: 8px;
  transition: background-color 0.3s;
}

.menu-item:hover {
  background-color: rgba(255, 255, 255, 0.2);
}
Enter fullscreen mode Exit fullscreen mode

Update your App.jsx:

// src/App.jsx
import React from 'react';
import AdvancedNavigation from './AdvancedNavigation';
import './App.css';

function App() {
  return (
    <div className="App">
      <AdvancedNavigation />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

This example demonstrates:

  • Responsive navigation (mobile vs desktop)
  • Multiple animation styles
  • Custom styling and theming
  • Icon support in menu items
  • State management for menu open/close
  • Smooth animations and transitions

Common Issues / Troubleshooting

  1. Menu not appearing: Make sure you've imported the CSS file (import 'react-burger-menu/lib/styles.css'). Also ensure the menu component is properly rendered and the isOpen state is being managed correctly.

  2. Menu not closing: Ensure you're calling the close function when menu items are clicked. Use onClick={() => setOpen(false)} on menu items.

  3. Styling conflicts: If the menu doesn't look right, check for CSS conflicts. You can override default styles using the styles prop on the menu component.

  4. Animation not working: Make sure you're importing the correct animation style component (e.g., slide, stack, elastic). Each style is a separate component.

  5. Menu positioning issues: Use the left or right props to control which side the menu slides in from. The default is left.

  6. State management: The menu state should be controlled by the isOpen prop. Use onStateChange to sync your state with the menu's internal state.

Next Steps

Now that you have an advanced understanding of react-burger-menu:

  • Explore all available animation styles
  • Learn about custom burger and cross icons
  • Implement keyboard navigation for accessibility
  • Add menu item animations and transitions
  • Integrate with React Router for navigation
  • Learn about other menu libraries (react-sidebar, react-slide-menu)
  • Check the official repository: https://github.com/negomi/react-burger-menu
  • Look for part 43 of this series for more advanced topics

Summary

You've successfully integrated react-burger-menu into your React application with advanced features including multiple animation styles, responsive navigation, custom styling, and comprehensive state management. react-burger-menu provides a flexible solution for creating animated slide-out navigation menus.

SEO Keywords

react-burger-menu
React slide-out menu
react-burger-menu tutorial
React animated navigation
react-burger-menu installation
React mobile menu
react-burger-menu example
React sidebar menu
react-burger-menu setup
React menu animations
react-burger-menu customization
React navigation component
react-burger-menu styles
React mobile navigation
react-burger-menu getting started

Top comments (0)