【发布时间】:2020-11-29 01:11:19
【问题描述】:
我正在尝试将 react-router 与侧边栏菜单中的材质 ui 集成,但它不起作用。当我单击菜单项时,只有 url 更改但组件不加载。我使用 [https://material-ui.com/guides/composition/#link] 上的指南进行了尝试,但每次尝试更改代码中的某些内容时都会得到奇怪的结果。我的应用组件如下,
layout.js
import React, {useCallback, useState} from 'react';
import clsx from 'clsx';
import {
Switch,
Route,
BrowserRouter as Router
}from 'react-router-dom';
import {
makeStyles,
useTheme
} from '@material-ui/core/styles';
import {
Drawer,
CssBaseline,
AppBar,
Toolbar,
IconButton,
Typography,
Divider,
List,
} from '@material-ui/core';
import MenuIcon from '@material-ui/icons/Menu';
import {MenuItem} from "./menu";
import {menu} from "./menuitems";
import {TheDowTheory} from "./DowTheory";
import {HomePage} from "../Home/Home";
const drawerWidth = 280;
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
menuButton: {
marginRight: 36,
},
hide: {
display: 'none',
},
drawer: {
width: drawerWidth,
flexShrink: 0,
whiteSpace: 'nowrap',
},
drawerOpen: {
width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
drawerClose: {
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
overflowX: 'hidden',
width: theme.spacing(7) + 1,
[theme.breakpoints.up('sm')]: {
width: theme.spacing(9) + 1,
},
},
toolbar: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
},
}));
export const MiniDrawer = () => {
const classes = useStyles();
const theme = useTheme();
const [open, setOpen] = useState(true);
const toggle = useCallback(
() => setOpen(!open),
[open],
);
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
position="fixed"
className={classes.appBar}
style={{backgroundColor:'white'}}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={toggle}
edge="start"
className={clsx(classes.menuButton, {
[classes.open]: !open,
})}
style={{color:'#10375c'}}
>
<MenuIcon />
</IconButton>
<Typography variant="h4"
noWrap
style={{color:'#10375c'}}
>
StockViz
</Typography>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
className={clsx(classes.drawer, {
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
})}
classes={{
paper: clsx({
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
}),
}}
>
<div className={classes.toolbar}>
<IconButton onClick={toggle} />
</div>
<Divider />
<List>
{menu.map((item, key) => <MenuItem key={key} item={item} />)}
</List>
</Drawer>
<main className={classes.content}>
<div className={classes.toolbar} />
<Router>
<Switch>
<Route exact path='/' component={HomePage} />
<Route exact path='/thedowtheory' component={TheDowTheory} />
</Switch>
</Router>
</main>
</div>
);
}
menu.js
import React, {forwardRef, Fragment, useMemo, useState} from 'react';
import { makeStyles } from '@material-ui/core/styles';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Collapse from '@material-ui/core/Collapse';
import ExpandLess from '@material-ui/icons/ExpandLess';
import ExpandMore from '@material-ui/icons/ExpandMore';
import {hasChildren} from "./utils";
import Divider from "@material-ui/core/Divider";
import {
Link,
BrowserRouter as Router,
} from "react-router-dom";
const useStyles = makeStyles((theme) => ({
link: {
textDecoration: 'none',
color: theme.palette.text.primary
}
}))
const SingleLevel = ({ item }) => {
const classes = useStyles();
return (
<Router>
<Link to={item.to} className={classes.link}>
<ListItem button>
<ListItemIcon>{item.icon}</ListItemIcon>
<ListItemText primary={item.title} />
</ListItem>
</Link>
</Router>
);
};
const MultiLevel = ({ item }) => {
const classes = useStyles();
const { items: children } = item;
const [open, setOpen] = useState(false);
const handleClick = () => {
setOpen((prev) => !prev);
};
return (
<Router>
<Link to={item.to} className={classes.link}>
<ListItem button onClick={handleClick}>
<ListItemIcon>{item.icon}</ListItemIcon>
<ListItemText primary={item.title} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component='div'
disablePadding
>
{children.map((child, key) => (
<MenuItem key={key} item={child} />
))}
</List>
</Collapse>
</Link>
</Router>
);
};
export const MenuItem = ({ item }) => {
const Component = hasChildren(item) ? MultiLevel : SingleLevel;
return <Component item={item} />;
};
menuitems.js
import HomeOutlinedIcon from "@material-ui/icons/HomeOutlined";
import LocalLibraryOutlinedIcon from "@material-ui/icons/LocalLibraryOutlined";
import TrendingUpOutlinedIcon from "@material-ui/icons/TrendingUpOutlined";
import DescriptionOutlinedIcon from "@material-ui/icons/DescriptionOutlined";
import React from "react";
import {HomePage} from "../Home/Home";
import {TheDowTheory} from "./DowTheory";
export const menu = [
{
icon: <HomeOutlinedIcon/>,
title: 'Home',
to: '/',
component: HomePage,
items: []
},
{
icon: <LocalLibraryOutlinedIcon/>,
title: 'Education',
items: [
{
title:'Technical Analysis',
items: [
{
title: 'Introduction',
component: 'Technical',
to: '/technical'
},
{
title: 'The Dow Theory',
component: TheDowTheory,
to: '/thedowtheory'
},
{
title: 'Charts & Chart Patterns',
component: 'Charts',
to: '/chart'
},
{
title: 'Trend & Trend Lines',
component: 'Trends',
to: '/trendlines'
},
{
title: 'Support & Resistance',
component: 'Support',
to: '/sandr'
},
]
},
{
title:'Fundamental Analysis',
items: [
{
title: 'Introduction',
component: 'Technical',
to: '/fundamental'
},
{
title: 'The Dow Theory',
component: 'Technical',
to: '/thedowtheory'
},
{
title: 'Charts & Chart Patterns',
component: 'Technical',
to: '/chart'
},
{
title: 'Trend & Trend Lines',
component: 'Technical',
to: '/trendlines'
},
{
title: 'Support & Resistance',
component: 'Technical',
to: '/sandr'
},
]
},
{
title:'Elliot Wave Analysis',
items: [
{
title: 'Introduction',
component: 'Technical',
to: '/elliot'
},
{
title: 'The Dow Theory',
component: 'Technical',
to: '/thedowtheory'
},
{
title: 'Charts & Chart Patterns',
component: 'Technical',
to: '/chart'
},
{
title: 'Trend & Trend Lines',
to: '/trendlines'
},
{
title: 'Support & Resistance',
to: '/sandr'
},
]
},
]
},
{
icon: <TrendingUpOutlinedIcon/>,
to: '/options',
component: 'Options',
title: 'Options'
},
{
icon: <DescriptionOutlinedIcon/>,
to: '/blog',
component: 'Blog',
title: 'Blog'
},
]
utils.js
import React from "react";
export function hasChildren(item) {
const { items: children } = item;
if (children === undefined) {
return false;
}
if (children.constructor !== Array) {
return false;
}
if (children.length === 0) {
return false;
}
return true;
}
【问题讨论】:
-
您的菜单项上是否需要有
component属性?我在家里看到component: HomePage。 -
我已经把它以编程方式路由它。目前我没有使用它
标签: reactjs react-router material-ui