Как перейти на страницу, нажав на гамбургер-меню?

Я начинаю с существующего проекта под названием Reaction-burger-menu.
https://github.com/negomi/react-burger-menu

Для навигации используется боковая панель меню-гамбургера. К сожалению, демонстрационный код не показывает, как на самом деле перейти на страницу конкретного элемента, по которому щелкнули. Вот код example.js, который возвращает боковое меню:

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'));

Он содержит два класса: MenuWrap и Demo. Функция render() класса Demo возвращает жестко закодированный HTML-код. Как перейти на другую страницу в зависимости от того, что нажимается в меню?

Обычно для этого реакция использует <Router> в файле index.js или app.js, например:

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

Я не могу понять, как совместить эти два метода. Может кто-нибудь прояснить?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Замените теги привязки (<a>) в getItems компонентами Link или NavLink и обновите правильные целевые пути.

Пример:

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>,
  ];
}

Убедитесь, что Demo отображается внутри маршрутизатора, чтобы компоненты Link могли получить доступ к предоставленному контексту маршрутизации.

<BrowserRouter>
  ...
  <Demo />
  ...
</BrowserRouter>
Ответ принят как подходящий

Я думаю, тебе стоит попробовать это. Я надеюсь, что это поможет вам

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'));

Другие вопросы по теме