首页 > 解决方案 > 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;

标签: reactjs

解决方案


您可以使用 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 );

推荐阅读