Question

How to go to a page clicked on a hamburger menu?

I'm starting with an existing project called react-burger-menu.
https://github.com/negomi/react-burger-menu

It uses a hamburger menu sidebar for navigation. Unfortunately, the demo code does not show how to actually go to a specific clicked item page. Here is the example.js code that returns the sidebar menu:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import BurgerMenu from 'react-burger-menu';
import classNames from 'classnames';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faHospitalUser,faHouseMedical } from '@fortawesome/free-solid-svg-icons'

class MenuWrap extends Component {
  constructor(props) {
    super(props);
    this.state = {
      hidden: false
    };
  }

  componentDidUpdate(prevProps) {
    const sideChanged =
      this.props.children.props.right !== prevProps.children.props.right;

    if (sideChanged) {
      this.setState({ hidden: true });

      setTimeout(() => {
        this.show();
      }, this.props.wait);
    }
  }

  show() {
    this.setState({ hidden: false });
  }

  render() {
    let style;

    if (this.state.hidden) {
      style = { display: 'none' };
    }

    return (
      <div style={style} className={this.props.side}>
        {this.props.children}
      </div>
    );
  }
}

class Demo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      currentMenu: 'scaleDown',
      side: 'left'
    };
  }

  changeMenu(menu) {
    this.setState({ currentMenu: menu });
  }

  changeSide(side) {
    this.setState({ side });
  }

  getItems() {

     let  items = [
          <a key="0" href="">
            <FontAwesomeIcon icon={faHouseMedical} fixedWidth/>
            <span>Home</span>
          </a>,
          <a key="1" href="">
            <FontAwesomeIcon icon={faHospitalUser} fixedWidth/>
            <span>Medical History</span>
          </a>,
        ];

    return items;
  }

  getMenu() {
    const Menu = BurgerMenu[this.state.currentMenu];

    return (
      <MenuWrap wait={20} side={this.state.side}>
        <Menu
          id={this.state.currentMenu}
          pageWrapId={'page-wrap'}
          outerContainerId={'outer-container'}
          right={this.state.side === 'right'}
        >
          {this.getItems()}
        </Menu>
      </MenuWrap>
    );
  }

  render() {
    const buttons = Object.keys(this.props.menus).map(menu => {
      return (
        <a
          key={menu}
          className={classNames({
            'current-demo': menu === this.state.currentMenu
          })}
          onClick={this.changeMenu.bind(this, menu)}
        >
          {this.props.menus[menu].buttonText}
        </a>
      );
    });

    // The following returns hard-coded html. How to return code depending on what is clicked?
    return (
      <div id="outer-container" style={{ height: '100%' }}>
        {this.getMenu()}
        <main id="page-wrap">
          <h1>
            <a href="https://github.com/negomi/react-burger-menu">
              react-burger-menu
            </a>
          </h1>
          <h2 className="description">
            An off-canvas sidebar React component with a collection of effects
            and styles using CSS transitions and SVG path animations.
          </h2>
          <nav className="demo-buttons">{buttons}</nav>
        </main>
      </div>
    );
  }
}

const menus = {
  slide: { buttonText: 'Slide', items: 1 },
  scaleDown: { buttonText: 'Scale Down', items: 2 },
};

ReactDOM.render(<Demo menus={menus} />, document.getElementById('app'));

It contains two classes, MenuWrap and Demo. The Demo class's render() function returns hard-coded html. How to go to a different page depending on what is clicked in the menu?

Typically react uses a <Router> to do that in the index.js or app.js file, as in:

import { BrowserRouter as Router, Route, Link, Routes } from "react-router-dom";

I can't figure out how to reconcile these two methods. Can someone clarify?

 3  50  3
1 Jan 1970

Solution

 1

Replace the anchor (<a>) tags in getItems with Link or NavLink components and update the correct target paths.

Example:

import { Link } from 'react-router-dom';

...

getItems() {
  return [
    <Link key="0" to="/">
      <FontAwesomeIcon icon={faHouseMedical} fixedWidth />
      <span>Home</span>
    </Link>,
    <Link key="1" to="/midical-history">
      <FontAwesomeIcon icon={faHospitalUser} fixedWidth />
      <span>Medical History</span>
    </Link>,
  ];
}

Ensure that Demo is rendered within a router so the Link components can access the provided routing context.

<BrowserRouter>
  ...
  <Demo />
  ...
</BrowserRouter>
2024-07-15
Drew Reese

Solution

 0

I think you should try this. I hope this would help you

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Link, Routes } from "react-router-dom";
import { Menu } from './Menu';
import { faClinic, faFileMedical } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

// Example components for different pages
const Dashboard = () => <div>Dashboard Page</div>;
const HealthRecords = () => <div>Health Records Page</div>;

class MenuWrap extends Component {
  constructor(props) {
    super(props);
    this.state = { hidden: false };
  }

  componentDidUpdate(prevProps) {
    const sideChanged = this.props.children.props.right !== prevProps.children.props.right;
    if (sideChanged) {
      this.setState({ hidden: true });
      setTimeout(() => { this.show(); }, this.props.wait);
    }
  }

  show() {
    this.setState({ hidden: false });
  }

  render() {
    const style = this.state.hidden ? { display: 'none' } : {};
    return <div style={style} className={this.props.side}>{this.props.children}</div>;
  }
}

class App extends Component {
  constructor(props) {
    super(props);
    this.state = { currentMenu: 'slide', side: 'left' };
  }

  changeMenu(menu) {
    this.setState({ currentMenu: menu });
  }

  changeSide(side) {
    this.setState({ side });
  }

  getItems() {
    return [
      <Link key="0" to="/">
        <FontAwesomeIcon icon={faClinic} fixedWidth />
        <span>Dashboard</span>
      </Link>,
      <Link key="1" to="/health-records">
        <FontAwesomeIcon icon={faFileMedical} fixedWidth />
        <span>Health Records</span>
      </Link>,
    ];
  }

  getMenu() {
    const MenuComponent = Menu[this.state.currentMenu];
    return (
      <MenuWrap wait={20} side={this.state.side}>
        <MenuComponent
          id={this.state.currentMenu}
          pageWrapId={'page-wrap'}
          outerContainerId={'outer-container'}
          right={this.state.side === 'right'}
        >
          {this.getItems()}
        </MenuComponent>
      </MenuWrap>
    );
  }

  render() {
    const buttons = Object.keys(this.props.menus).map(menu => (
      <a
        key={menu}
        className={classNames({ 'current-demo': menu === this.state.currentMenu })}
        onClick={() => this.changeMenu(menu)}
      >
        {this.props.menus[menu].buttonText}
      </a>
    ));

    return (
      <Router>
        <div id="outer-container" style={{ height: '100%' }}>
          {this.getMenu()}
          <main id="page-wrap">
            <h1>
              Health Care App
            </h1>
            <h2 className="description">
              A simple health care app with a responsive menu
            </h2>
            <nav className="demo-buttons">{buttons}</nav>
            <Routes>
              <Route path="/" element={<Dashboard />} />
              <Route path="/health-records" element={<HealthRecords />} />
            </Routes>
          </main>
        </div>
      </Router>
    );
  }
}

const menus = {
  slide: { buttonText: 'Slide', items: 1 },
  scaleDown: { buttonText: 'Scale Down', items: 2 },
};

ReactDOM.render(<App menus={menus} />, document.getElementById('app'));

2024-07-15
Akhilesh Saini