Reactjs 将react router与物料ui集成不起作用
我试图将react router与侧边栏菜单中的材质ui集成,但它不起作用。当我点击菜单项时,只有url会改变,但组件不会加载。我戴着导游试过了[https://material-ui.com/guides/composition/#link],但每次我试图更改代码时都会得到奇怪的结果。我的应用程序组件如下所示 layout.jsReactjs 将react router与物料ui集成不起作用,reactjs,react-router,material-ui,Reactjs,React Router,Material Ui,我试图将react router与侧边栏菜单中的材质ui集成,但它不起作用。当我点击菜单项时,只有url会改变,但组件不会加载。我戴着导游试过了[https://material-ui.com/guides/composition/#link],但每次我试图更改代码时都会得到奇怪的结果。我的应用程序组件如下所示 layout.js import React, {useCallback, useState} from 'react'; import clsx from 'clsx'; import
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>
);
}
组件
菜单
必须位于路由器
内,如果您想直接指向另一个组件。@Yogendra Kumar此答案是此答案的延续。我将使用相同的增强代码来添加对React路由器的支持
首先,我将把
SingleLevel
组件从react-router-dom
更改为使用Link
组件。这可以通过将component={Link}
传递到ListItem
来完成。还值得注意的是,如果当前项目没有to
属性,我希望用户被重定向到404页面
阅读有关集成路由器dom
到材质ui
的指南
从“react router dom”导入{Link};
...
常量单级=({item})=>{
返回(
{item.icon}
);
};
对于multivel
的ListItem
组件,不需要进行此更改,因为我们不希望在单击其项目时将用户链接到页面,而只显示其折叠的项目
接下来,我将创建一个路由
组件,该组件将包含我的所有路由配置
react路由器dom
Routes.js
导出默认函数路由(){
返回(
);
}
最后,我将把App.js
文件重命名为Nav.js
,因为我不想用App.js
来代替这些代码
从“react Router dom”导入{BrowserRouter as Router};
从“/Nav”导入Nav;
从“/Routes”导入路由;
导出默认函数App(){
返回(
);
}
@Yogendra Kumar,此解决方案不考虑文件
layout.js
中menu.js
哪个菜单组件的component
属性。将标签Router
作为此组件的父标签移出。您可以将代码放在codepen.io上吗。所以我们可以看看这个。您的菜单项上是否需要有component
属性?我看到了家庭的组件:主页
。我把它放在编程的路径上。目前我没有使用它
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} />;
};
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'
},
]
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;
}