最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to add react routing to AntD horizontal Menu? - Stack Overflow

programmeradmin1浏览0评论

I have the below ponent as the main layout. When I click on the menu item, I want them to navigate to the home, holiday calendar, and event pages. What can I do with this horizontal menu? The below code shows the main layout wrapped around the above pages. I am using AntD and react-router. this main layout is wrapped around all other routers.

import { Layout, Menu, Button, Avatar, Row, Col, Space, Dropdown } from "antd";
import React, { useState } from "react";
import { Outlet } from "react-router-dom";

const navigation = [
  { label: "Home", key: 1 },
  { label: "Holiday Calendar", key: 2 },
  { label: "Event", key: 3 },
];

const MainLayout = () => {

  const [open, setOpen] = useState(false);

  const showDrawer = () => {
    setOpen(true);
  };

  const onClose = () => {
    setOpen(false);
    window.dispatchEvent(new Event("loadHolidayCalander"));
  };

  const handleLogOut = () => {
    localStorage.removeItem("access-token");

  };
  const menu = (
    <Menu
      items={[
        {
          key: "1",
          label: <Button onClick={handleLogOut}>Log out</Button>,
        },
      ]}
    ></Menu>
  );

  return (
    <Layout style={{backgroundColor:"white"}}>      
        <Row style={{ backgroundColor:"#404140"}}>
          <Col
          style={{padding:5, margin:0, height:48}}
            flex="300px"
           >
            <a href="/holiday-calander">
              <img src="/logo.png" alt="logo" style={{ height: 38 }} />
            </a>
          </Col>
          <Col>
            <Menu              
              theme="dark"
              mode="horizontal"
              defaultSelectedKeys={["2"]}
              items={navigation}
            />
          </Col>
          <Col
            flex="auto"
            style={{

              padding:5

            }}
          >
            <div style={{ position: "absolute", right: "5px" }}>
              <Space size={20}>
                <Dropdown overlay={menu} placement="topRight" arrow>
                  <Avatar  style={{ width: 38, height:38 }} />
                </Dropdown>
              </Space>
            </div>
          </Col>

        </Row>
        
    
      <Layout
        style={{
          padding: 0,
          backgroundColor: "white",
          marginLeft:28,
          marginRight:28,
        }}
      >

        <Outlet />

      </Layout>
    </Layout>
  );
};

export default MainLayout;


I have the below ponent as the main layout. When I click on the menu item, I want them to navigate to the home, holiday calendar, and event pages. What can I do with this horizontal menu? The below code shows the main layout wrapped around the above pages. I am using AntD and react-router. this main layout is wrapped around all other routers.

import { Layout, Menu, Button, Avatar, Row, Col, Space, Dropdown } from "antd";
import React, { useState } from "react";
import { Outlet } from "react-router-dom";

const navigation = [
  { label: "Home", key: 1 },
  { label: "Holiday Calendar", key: 2 },
  { label: "Event", key: 3 },
];

const MainLayout = () => {

  const [open, setOpen] = useState(false);

  const showDrawer = () => {
    setOpen(true);
  };

  const onClose = () => {
    setOpen(false);
    window.dispatchEvent(new Event("loadHolidayCalander"));
  };

  const handleLogOut = () => {
    localStorage.removeItem("access-token");

  };
  const menu = (
    <Menu
      items={[
        {
          key: "1",
          label: <Button onClick={handleLogOut}>Log out</Button>,
        },
      ]}
    ></Menu>
  );

  return (
    <Layout style={{backgroundColor:"white"}}>      
        <Row style={{ backgroundColor:"#404140"}}>
          <Col
          style={{padding:5, margin:0, height:48}}
            flex="300px"
           >
            <a href="/holiday-calander">
              <img src="/logo.png" alt="logo" style={{ height: 38 }} />
            </a>
          </Col>
          <Col>
            <Menu              
              theme="dark"
              mode="horizontal"
              defaultSelectedKeys={["2"]}
              items={navigation}
            />
          </Col>
          <Col
            flex="auto"
            style={{

              padding:5

            }}
          >
            <div style={{ position: "absolute", right: "5px" }}>
              <Space size={20}>
                <Dropdown overlay={menu} placement="topRight" arrow>
                  <Avatar  style={{ width: 38, height:38 }} />
                </Dropdown>
              </Space>
            </div>
          </Col>

        </Row>
        
    
      <Layout
        style={{
          padding: 0,
          backgroundColor: "white",
          marginLeft:28,
          marginRight:28,
        }}
      >

        <Outlet />

      </Layout>
    </Layout>
  );
};

export default MainLayout;


Share Improve this question edited Nov 6, 2022 at 19:00 Drew Reese 203k17 gold badges237 silver badges268 bronze badges asked Nov 6, 2022 at 18:34 DmapDmap 1991 gold badge6 silver badges21 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

You can add an onClick handler to the Menu ponent, which will be passed an object with the key property you can search the navigation array for the matching element.

Add a link target to the navigation array elements.

import { ..., useNavigate, ... } from 'react-router-dom';

...

const navigation = [
  { label: "Home", key: 1, target: "/" },
  { label: "Holiday Calendar", key: 2, "/holidaycalendar" },
  { label: "Event", key: 3, "/event" },
];

...

const navigate = useNavigate();

const handleMenuClick = ({ key }) => {
  const { target } = navigation.find(item => item.key === key) || {};
  if (target) {
    navigate(target);
  }
};

...

<Menu              
  theme="dark"
  mode="horizontal"
  defaultSelectedKeys={["2"]}
  items={navigation}
  onClick={handleMenuClick}
/>

An improvement could be to make the key property the link target.

import { ..., useNavigate, ... } from 'react-router-dom';

...

const navigation = [
  { label: "Home", key: "/" },
  { label: "Holiday Calendar", key: "/holidaycalendar" },
  { label: "Event", key: "/event" },
];

...

const navigate = useNavigate();

const handleMenuClick = ({ key }) => {
  if (key) {
    navigate(key);
  }
};

...

<Menu              
  theme="dark"
  mode="horizontal"
  defaultSelectedKeys={["/holidaycalendar"]}
  items={navigation}
  onClick={handleMenuClick}
/>

Actually you can pass Link ponent from rrd to label property in Menu.item as state in this link.

Example :

import {Link} from 'react-router-dom';
...

items = [
    {
        key: '/home',
        label: <Link to='/home'>Home</Link>,
        icon: <SomeIcon />,
    },
    {
        key: '/menu',
        label: 'This is parent menu',
        icon: <SomeIcon />,
        children: [
            {
                key: '/menu-1',
                label: '<Link to='/menu-1'>Sub Menu 1</Link>,
                icon: <MenuIcon1 />,
            },
            {
                key: '/menu-2',
                label: '<Link to='/menu-2'>Sub Menu 2</Link>,
                icon: <MenuIcon2 />,
            },
    },
]

If you're using React Router 6, you can set id for each of your routes and use it to match it to the correct Menu item.

import { useLocation, matchRoutes, createBrowserRouter } from 'react-router-dom';

...

const routes = [
  { id: 'layout', path: '/', element, children: [
    { id: 'home', index: true, element },
    ...
  ] },
  ...
];

const router = createBrowserRouter(routes);

...

const currentRoutes = matchRoutes(routes, location);
const currentRoutesIds = currentRoutes?.map((r) => r.route.id);

...

const items = [
  {
    key: 'home',
    label: <NavLink to="/">Home</NavLink>,
  },
  {
    key: 'other',
    label: <NavLink to="/other">Some other route</NavLink>,
  },
  ...
];

...

<Menu              
  selectedKeys={currentRoutesIds}
  items={items}
/>
发布评论

评论列表(0)

  1. 暂无评论