Я начинаю с существующего проекта под названием 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";
Я не могу понять, как совместить эти два метода. Может кто-нибудь прояснить?
Замените теги привязки (<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'));