Linking href in Material UI 动态网站中的抽屉组件
Linking href in Material UI Drawer Component in dynamic website
我正在尝试使用 Material UI 的抽屉组件 (https://material-ui.com/components/drawers/) 来设置导航栏。当我在项目中使用此代码时,我不确定如何正确地 link href,以便用户可以单击主菜单按钮并路由到不同的页面。我在我创建的不同页面的每个函数中都使用了 history.push,但不确定如何 link 它。
import React, { useEffect, useState } from 'react'
import { makeStyles } from '@material-ui/core/styles';
import { Drawer, Button, List, Divider, ListItem, ListItemIcon, ListItemText, AppBar, IconButton, Toolbar, Typography, Collapse } from '@material-ui/core';
import { Link } from 'react-router-dom';
import { useHistory } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
import clsx from 'clsx';
import SortIcon from '@material-ui/icons/Sort';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import MailIcon from '@material-ui/icons/Mail';
import HomeIcon from '@material-ui/icons/Home';
import LockOpenIcon from '@material-ui/icons/LockOpen'; // log in
import ExitToAppIcon from '@material-ui/icons/ExitToApp'; // sign out
import AccountCircleIcon from '@material-ui/icons/AccountCircle'; //user profile?
import GroupIcon from '@material-ui/icons/Group'; // team
import AccountBoxIcon from '@material-ui/icons/AccountBox';
import wecycle from '../images/wecycle_logo.PNG';
const useStyles = makeStyles((theme) => ({
main: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
/*height: "100vh",*/
fontFamily: "Roboto",
},
navbar: {
backgroundColor: "white",
},
navbarContent: {
width: "100%",
margin: "0 auto",
},
navbarTitle: {
fontSize: "2rem",
flexGrow: '2',
},
icon: {
color: 'black',
fontSize: "2rem",
},
colorText: {
color: "#5AFF3D",
},
container: {
textAlign: "center",
},
title: {
color: "#fff",
fontSize: "2.5rem",
},
list: { //NEW
width: 250,
},
fullList: {
width: 'auto',
},
wecycleLogo: {
width: "115px",
height: "50px",
}
}));
/**
* The code line 63 to 147 is composed of Material UI Drawer Component code.
* Please refer to https://material-ui.com/components/drawers/ for 'Temporary Drawer'
*
* @returns header
*/
export default function Header() {
const classes = useStyles();
const {currentUser, logout } = useAuth();
const [error, setError] = useState("");
const history = useHistory();
function aboutUsRedirect() {
history.push("/aboutUs");
}
function landingRedirect() {
history.push("/");
}
function loginRedirect() {
history.push("/login");
}
function signupRedirect() {
history.push("/signup");
}
async function handleLogout() {
setError('');
try {
await logout();
history.pushState("/");
} catch {
setError("Failed to log out");
}
}
const [state, setState] = React.useState({
right: false,
});
const toggleDrawer = (anchor, open) => (event) => {
if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
return;
}
setState({ ...state, [anchor]: open });
};
const list = (anchor) => (
<div
className={clsx(classes.list, {
[classes.fullList]: anchor === 'top' || anchor === 'bottom',
})}
role="presentation"
onClick={toggleDrawer(anchor, false)}
onKeyDown={toggleDrawer(anchor, false)}
>
<List>
{['Home', 'Log In', 'Sign Up'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>{index % 2 === 0 ? <HomeIcon /> : <MailIcon />}</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
<Divider />
<List>
{['Profile', 'About'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>{index % 2 === 0 ? <AccountBoxIcon /> : <GroupIcon />}</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</div>
);
return (
<div className={classes.main} id="header">
<AppBar className={classes.navbar}>
<Toolbar className={classes.navbarContent}>
<h1 className={classes.navbarTitle}>
<img src = {wecycle} className={classes.wecycleLogo} />
</h1>
<IconButton>
{['right'].map((anchor) => (
<React.Fragment key={anchor}>
<IconButton onClick={toggleDrawer(anchor, true)}>
<SortIcon className={classes.icon} />
</IconButton>
<Drawer anchor={anchor} open={state[anchor]} onClose={toggleDrawer(anchor, false)}>
{list(anchor)}
</Drawer>
</React.Fragment>
))}
</IconButton>
</Toolbar>
</AppBar>
</div>
);
}
您可以将回调附加到 ListItem
组件。
<ListItem button onClick={clickHandler}>
<ListItemIcon>
<IconComponent />
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
您可以通过将更多数据移动到正在映射的数组中来优化项目映射。
const menuItems = [
{
text: 'Home',
icon: HomeIcon,
onClick: () => history.push("/"),
},
{
text: 'Log In',
icon: MailIcon,
onClick: () => history.push("/login"),
},
{
text: 'Sign Up',
icon: HomeIcon,
onClick: () => history.push("/signup"),
},
];
...
<List>
{menuItems.map(({ text, icon: Icon, onClick}, index) => (
<ListItem button key={text} onClick={onClick}>
<ListItemIcon>
<Icon />
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
我正在尝试使用 Material UI 的抽屉组件 (https://material-ui.com/components/drawers/) 来设置导航栏。当我在项目中使用此代码时,我不确定如何正确地 link href,以便用户可以单击主菜单按钮并路由到不同的页面。我在我创建的不同页面的每个函数中都使用了 history.push,但不确定如何 link 它。
import React, { useEffect, useState } from 'react'
import { makeStyles } from '@material-ui/core/styles';
import { Drawer, Button, List, Divider, ListItem, ListItemIcon, ListItemText, AppBar, IconButton, Toolbar, Typography, Collapse } from '@material-ui/core';
import { Link } from 'react-router-dom';
import { useHistory } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
import clsx from 'clsx';
import SortIcon from '@material-ui/icons/Sort';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import MailIcon from '@material-ui/icons/Mail';
import HomeIcon from '@material-ui/icons/Home';
import LockOpenIcon from '@material-ui/icons/LockOpen'; // log in
import ExitToAppIcon from '@material-ui/icons/ExitToApp'; // sign out
import AccountCircleIcon from '@material-ui/icons/AccountCircle'; //user profile?
import GroupIcon from '@material-ui/icons/Group'; // team
import AccountBoxIcon from '@material-ui/icons/AccountBox';
import wecycle from '../images/wecycle_logo.PNG';
const useStyles = makeStyles((theme) => ({
main: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
/*height: "100vh",*/
fontFamily: "Roboto",
},
navbar: {
backgroundColor: "white",
},
navbarContent: {
width: "100%",
margin: "0 auto",
},
navbarTitle: {
fontSize: "2rem",
flexGrow: '2',
},
icon: {
color: 'black',
fontSize: "2rem",
},
colorText: {
color: "#5AFF3D",
},
container: {
textAlign: "center",
},
title: {
color: "#fff",
fontSize: "2.5rem",
},
list: { //NEW
width: 250,
},
fullList: {
width: 'auto',
},
wecycleLogo: {
width: "115px",
height: "50px",
}
}));
/**
* The code line 63 to 147 is composed of Material UI Drawer Component code.
* Please refer to https://material-ui.com/components/drawers/ for 'Temporary Drawer'
*
* @returns header
*/
export default function Header() {
const classes = useStyles();
const {currentUser, logout } = useAuth();
const [error, setError] = useState("");
const history = useHistory();
function aboutUsRedirect() {
history.push("/aboutUs");
}
function landingRedirect() {
history.push("/");
}
function loginRedirect() {
history.push("/login");
}
function signupRedirect() {
history.push("/signup");
}
async function handleLogout() {
setError('');
try {
await logout();
history.pushState("/");
} catch {
setError("Failed to log out");
}
}
const [state, setState] = React.useState({
right: false,
});
const toggleDrawer = (anchor, open) => (event) => {
if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
return;
}
setState({ ...state, [anchor]: open });
};
const list = (anchor) => (
<div
className={clsx(classes.list, {
[classes.fullList]: anchor === 'top' || anchor === 'bottom',
})}
role="presentation"
onClick={toggleDrawer(anchor, false)}
onKeyDown={toggleDrawer(anchor, false)}
>
<List>
{['Home', 'Log In', 'Sign Up'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>{index % 2 === 0 ? <HomeIcon /> : <MailIcon />}</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
<Divider />
<List>
{['Profile', 'About'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>{index % 2 === 0 ? <AccountBoxIcon /> : <GroupIcon />}</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</div>
);
return (
<div className={classes.main} id="header">
<AppBar className={classes.navbar}>
<Toolbar className={classes.navbarContent}>
<h1 className={classes.navbarTitle}>
<img src = {wecycle} className={classes.wecycleLogo} />
</h1>
<IconButton>
{['right'].map((anchor) => (
<React.Fragment key={anchor}>
<IconButton onClick={toggleDrawer(anchor, true)}>
<SortIcon className={classes.icon} />
</IconButton>
<Drawer anchor={anchor} open={state[anchor]} onClose={toggleDrawer(anchor, false)}>
{list(anchor)}
</Drawer>
</React.Fragment>
))}
</IconButton>
</Toolbar>
</AppBar>
</div>
);
}
您可以将回调附加到 ListItem
组件。
<ListItem button onClick={clickHandler}>
<ListItemIcon>
<IconComponent />
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
您可以通过将更多数据移动到正在映射的数组中来优化项目映射。
const menuItems = [
{
text: 'Home',
icon: HomeIcon,
onClick: () => history.push("/"),
},
{
text: 'Log In',
icon: MailIcon,
onClick: () => history.push("/login"),
},
{
text: 'Sign Up',
icon: HomeIcon,
onClick: () => history.push("/signup"),
},
];
...
<List>
{menuItems.map(({ text, icon: Icon, onClick}, index) => (
<ListItem button key={text} onClick={onClick}>
<ListItemIcon>
<Icon />
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>