reactjs - React.js:如何在单击菜单时重定向到另一个页面?
问题描述
我有一个侧面导航,在我的路由页面中被调用
侧导航工作正常,但是,我想在单击菜单项时重定向到另一个页面
就像发生在<NavLink to="/">
Sidebar.js
import React from "react";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import Divider from "@material-ui/core/Divider";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ExpandLessIcon from "@material-ui/icons/ExpandLess";
import Collapse from "@material-ui/core/Collapse";
import logo from "../assets/sbc-logo.png";
function SidebarItem({ depthStep = 10, depth = 0, expanded, item, ...rest }) {
const [collapsed, setCollapsed] = React.useState(true);
const { label, items, Icon, onClick: onClickProp } = item;
function toggleCollapse() {
setCollapsed(prevValue => !prevValue);
}
function onClick(e) {
if (Array.isArray(items)) {
toggleCollapse();
}
if (onClickProp) {
onClickProp(e, item);
}
}
let expandIcon;
if (Array.isArray(items) && items.length) {
expandIcon = !collapsed ? (
<ExpandLessIcon
className={
"sidebar-item-expand-arrow" + " sidebar-item-expand-arrow-expanded"
}
/>
) : (
<ExpandMoreIcon className="sidebar-item-expand-arrow" />
);
}
return (
<>
<ListItem
className="sidebar-item"
onClick={onClick}
button
dense
{...rest}
>
<div
style={{ paddingLeft: depth * depthStep }}
className="sidebar-item-content"
>
{Icon && <Icon className="sidebar-item-icon" fontSize="small" />}
<div className="sidebar-item-text">{label}</div>
</div>
{expandIcon}
</ListItem>
<Collapse in={!collapsed} timeout="auto" unmountOnExit>
{Array.isArray(items) ? (
<List disablePadding dense>
{items.map((subItem, index) => (
<React.Fragment key={`${subItem.name}${index}`}>
{subItem === "divider" ? (
<Divider style={{ margin: "6px 0" }} />
) : (
<SidebarItem
depth={depth + 1}
depthStep={depthStep}
item={subItem}
/>
)}
</React.Fragment>
))}
</List>
) : null}
</Collapse>
</>
);
}
function Sidebar({ items, depthStep, depth, expanded }) {
return (
<div className="sidebar-fixed position-fixed">
{<a href="#!" className="logo-wrapper waves-effect">
<img alt="MDB React Logo" className="img-fluid" src={logo}/>
</a>}
<List disablePadding dense>
{items.map((sidebarItem, index) => (
<React.Fragment key={`${sidebarItem.name}${index}`}>
{sidebarItem === "divider" ? (
<Divider style={{ margin: "6px 0" }} />
) : (
<SidebarItem
depthStep={depthStep}
depth={depth}
expanded={expanded}
item={sidebarItem}
/>
)}
</React.Fragment>
))}
</List>
</div>
);
}
export default Sidebar;
AuthenticatedPage.js
import React, { Component } from 'react'
import TopNavigation from '../topNavigation'
import SideNavigation from '../sideNavigation'
import Routes from '../Routes'
import Footer from '../Footer'
import IdleTimer from 'react-idle-timer'
import { IdleTimeOutModal } from '../modals/IdleTimeoutModal'
import PropertyService from '../../services/PropertyService'
import SwapHorizIcon from "@material-ui/icons/SwapHoriz"
import InboxIcon from "@material-ui/icons/Inbox"
import PresentToAllIcon from '@material-ui/icons/PresentToAll';
import ThumbUpIcon from '@material-ui/icons/ThumbUp';
import SettingsPowerIcon from '@material-ui/icons/SettingsPower';
import ListIcon from '@material-ui/icons/List';
import LanguageIcon from '@material-ui/icons/Language';
import ListAltIcon from '@material-ui/icons/ListAlt';
import DescriptionIcon from '@material-ui/icons/Description';
import MoneyIcon from '@material-ui/icons/Money';
import FaceIcon from '@material-ui/icons/Face';
import TransferWithinAStationIcon from '@material-ui/icons/TransferWithinAStation';
import AttachMoneyIcon from '@material-ui/icons/AttachMoney';
import PersonPinCircleIcon from '@material-ui/icons/PersonPinCircle';
import EditIcon from '@material-ui/icons/Edit';
import SettingsIcon from "@material-ui/icons/Settings";
import SupervisorAccountIcon from '@material-ui/icons/SupervisorAccount';
import PermContactCalendarIcon from '@material-ui/icons/PermContactCalendar';
import Sidebar from '../Sidebar'
function onClick(e, item) {
console.log("onClick e", e)
console.log("onClick item", item)
}
const items = [
// { name: "dashboard", label: "Dashboard", Icon: HomeIcon },
{
name: "transfers",
label: "Transfers",
Icon: SwapHorizIcon,
items: [
{ name: "inbox", label: "Inbox", Icon: InboxIcon, onClick },
{ name: "sent", label: "Sent", Icon: PresentToAllIcon, onClick },
{ name: "acknowledged", label: "Acknowledged", Icon: ThumbUpIcon, onClick },
{ name: "bcpmode", label: "BCP Mode", Icon: SettingsPowerIcon, onClick }
]
},
{
name: "prooflist",
label: "Proof List",
Icon: ListIcon,
items: [
{ name: "proofweb", label: "Proof Web", Icon: LanguageIcon, onClick },
{ name: "proofothers", label: "Proof Others", Icon: ListAltIcon, onClick }
]
},
{
name: "miscellaneous",
label: "Miscellaneous",
Icon: DescriptionIcon
},
{
name: "rps",
label: "RPS",
Icon: MoneyIcon,
items: [
{ name: "clientmaintenance", label: "Client Maintenance", Icon: FaceIcon, onClick },
{ name: "processsftp", label: "Process SFTP", Icon: TransferWithinAStationIcon, onClick },
{ name: "processpesonet", label: "Process PESONet", Icon: AttachMoneyIcon, onClick },
{ name: "overrideenrollment", label: "Override Enrollment", Icon: PersonPinCircleIcon, onClick },
]
},
{
name: "messageconverter",
label: "Message Converter",
Icon: EditIcon
},
"divider",
{
name: "administrator",
label: "Administrator",
Icon: SettingsIcon,
items: [
{ name: "usermaintenance", label: "User Maintenance", Icon: SupervisorAccountIcon, onClick },
{ name: "profilemaintenance", label: "Profile Maintenance", Icon: PermContactCalendarIcon, onClick }
]
}
];
class AuthenticatedPage extends Component {
constructor(props){
super(props)
this.state = {
// timeout: 1000 * 60 * 15, /*15 mins - Initial value only, final is from property file*/
showModal: false,
userLoggedIn: false,
isTimedOut: false
}
this.idleTimer = null
this.onAction = this._onAction.bind(this)
this.onActive = this._onActive.bind(this)
this.onIdle = this._onIdle.bind(this)
this.handleClose = this.handleClose.bind(this)
this.handleLogout = this.handleLogout.bind(this)
}
_onAction(e) {
this.setState({isTimedOut: false})
}
_onActive(e) {
this.setState({isTimedOut: false})
}
_onIdle(e) {
const isTimedOut = this.state.isTimedOut
if (isTimedOut) {
} else {
this.setState({showModal: true})
this.idleTimer.reset();
this.setState({isTimedOut: true})
}
}
handleClose() {
this.setState({showModal: false})
}
handleLogout() {
this.setState({
showModal: false
});
this.props.history.push('/')
}
componentWillMount(){ /* should be called not only once */
PropertyService
.retrieveAllProperties()
.then((response) => {
this.setState({ timeout: response.data.timeout })
})
}
render() {
const { match } = this.props
return (
<React.Fragment>
<IdleTimer
ref={ref => { this.idleTimer = ref }}
element={document}
onActive={this.onActive}
onIdle={this.onIdle}
onAction={this.onAction}
debounce={250}
timeout={this.state.timeout} />
<div>
<TopNavigation />
{/* <SideNavigation /> */}
<Sidebar items={items}/>
<main id="content" className="p-5">
<Routes />
</main>
<Footer />
</div>
<IdleTimeOutModal
showModal={this.state.showModal}
handleClose={this.handleClose}
handleLogout={this.handleLogout}
/>
</React.Fragment>
)
}
}
export default AuthenticatedPage
如您所见,我在 AuthenticatedPage 中有一个 onClick 函数
我怎样才能从那里重定向?
history.push
因为不知道能不能拿到道具,所以无法工作
抱歉还是 React 的初学者,这些事情让我很困惑
TIA
--EDIT-- 转换AuthenticatedPage.js
为功能组件
import React from 'react';
import TopNavigation from '../topNavigation'
import SideNavigation from '../sideNavigation'
import Routes from '../Routes'
import Footer from '../Footer'
import Sidebar from '../Sidebar'
import SwapHorizIcon from "@material-ui/icons/SwapHoriz"
import InboxIcon from "@material-ui/icons/Inbox"
import PresentToAllIcon from '@material-ui/icons/PresentToAll';
import ThumbUpIcon from '@material-ui/icons/ThumbUp';
import SettingsPowerIcon from '@material-ui/icons/SettingsPower';
import ListIcon from '@material-ui/icons/List';
import LanguageIcon from '@material-ui/icons/Language';
import ListAltIcon from '@material-ui/icons/ListAlt';
import DescriptionIcon from '@material-ui/icons/Description';
import MoneyIcon from '@material-ui/icons/Money';
import FaceIcon from '@material-ui/icons/Face';
import TransferWithinAStationIcon from '@material-ui/icons/TransferWithinAStation';
import AttachMoneyIcon from '@material-ui/icons/AttachMoney';
import PersonPinCircleIcon from '@material-ui/icons/PersonPinCircle';
import EditIcon from '@material-ui/icons/Edit';
import SettingsIcon from "@material-ui/icons/Settings";
import SupervisorAccountIcon from '@material-ui/icons/SupervisorAccount';
import PermContactCalendarIcon from '@material-ui/icons/PermContactCalendar';
import { useHistory } from "react-router-dom";
function onClick(item){
let history = useHistory();
history.push(item);
}
const items = [
// { name: "dashboard", label: "Dashboard", Icon: HomeIcon },
{
name: "transfers",
label: "Transfers",
Icon: SwapHorizIcon,
items: [
{ name: "/inbox", label: "Inbox", Icon: InboxIcon, onClick },
{ name: "/sent", label: "Sent", Icon: PresentToAllIcon, onClick },
{ name: "/acknowledged", label: "Acknowledged", Icon: ThumbUpIcon, onClick },
{ name: "/bcpmode", label: "BCP Mode", Icon: SettingsPowerIcon, onClick }
]
},
{
name: "prooflist",
label: "Proof List",
Icon: ListIcon,
items: [
{ name: "/proofweb", label: "Proof Web", Icon: LanguageIcon, onClick },
{ name: "/proofothers", label: "Proof Others", Icon: ListAltIcon, onClick }
]
},
{
name: "/miscellaneous",
label: "Miscellaneous",
Icon: DescriptionIcon
},
{
name: "rps",
label: "RPS",
Icon: MoneyIcon,
items: [
{ name: "/clientmaintenance", label: "Client Maintenance", Icon: FaceIcon, onClick },
{ name: "/processsftp", label: "Process SFTP", Icon: TransferWithinAStationIcon, onClick },
{ name: "/processpesonet", label: "Process PESONet", Icon: AttachMoneyIcon, onClick },
{ name: "/overrideenrollment", label: "Override Enrollment", Icon: PersonPinCircleIcon, onClick },
]
},
{
name: "/messageconverter",
label: "Message Converter",
Icon: EditIcon
},
"divider",
{
name: "administrator",
label: "Administrator",
Icon: SettingsIcon,
items: [
{ name: "/usermaintenance", label: "User Maintenance", Icon: SupervisorAccountIcon, onClick },
{ name: "/profilemaintenance", label: "Profile Maintenance", Icon: PermContactCalendarIcon, onClick }
]
}
];
function AuthenticatedPage(props) {
return (
<div>
<div>
<TopNavigation />
{/* <SideNavigation /> */}
<Sidebar items={items}/>
<main id="content" className="p-5">
<Routes />
</main>
<Footer />
</div>
</div>
);
}
export default AuthenticatedPage;
解决方案
您可以使用 UseHistory 并通过点击导航到 url,如下所示
功能组件:
import { useHistory } from "react-router-dom";
function handleClick() {
let history = useHistory();
history.push("/home");
}
类组件:
import { withRouter } from 'react-router-dom';
function handleClick() {
this.props.history.push("/home");
}
export default withRouter(AuthenticatedPage );
推荐阅读
- xpath - 我可以在机器人框架中获取 xpath 计数值吗
- r - 从一列中分离百万和十亿数据
- ios - main.async 中的块仅在 global.async 块完成后执行
- mongodb - Spring boot / mongo 不会使用索引注释创建索引
- perl - 如何以相反的方式打印 subhash 的第一个元素 Perl
- ms-access - Access 365:在查询中查找最早的日期
- gis - OpenLayers 5:笔画宽度缩放?
- sql - 如何通过最大值知道其他列的值(PostgreSQL)?
- database - MongoDB 是否使用严格单调递增的 ID 导出?
- vue.js - 如何覆盖 Vue-cli3 中的环境变量?