如何通过React Router的pathname同时高亮Antd两个独立组件的Menu.Item
问题原因
你当前封装的Menu组件没有主动控制selectedKeys,Antd Menu默认的选中逻辑是匹配和当前路径完全相等的key,当访问/z/b时,主菜单的key为/z,和当前路径不完全匹配,因此不会高亮。另外不要使用defaultSelectedKeys,该属性仅在组件首次渲染时生效,路由切换后不会更新选中状态,必须用受控的selectedKeys属性。
解决方案
1. 改造封装的MenuItems组件
引入React Router的useLocation钩子获取当前路由路径,区分主菜单和二级菜单的匹配逻辑:主菜单做前缀匹配,只要当前路径以主路由path开头就标记为选中;二级菜单做完全路径匹配。
import { useLocation } from 'react-router-dom'; import { Menu } from 'antd'; import { Link } from 'react-router-dom'; const MenuItems = ({ routes, isMainMenu = false, theme, mode, ...items }) => { const { pathname } = useLocation(); // 计算选中的菜单项key const getSelectedKeys = () => { if (isMainMenu) { // 主菜单前缀匹配,找到当前路径归属的父路由 const matchedParentPath = routes.find(route => pathname.startsWith(route.path))?.path; return matchedParentPath ? [matchedParentPath] : []; } // 二级菜单完全匹配当前路径 return [pathname]; }; const menuItems = routes.map(({ name, path }) => ( <Menu.Item key={path}> <Link to={path}>{name}</Link> </Menu.Item> )); return ( <Menu theme={theme} mode={mode} selectedKeys={getSelectedKeys()} {...items} > {menuItems} </Menu> ); };
2. 调整组件调用方式
主菜单调用时传入isMainMenu标识,开启前缀匹配逻辑:
{/* 根路径主菜单 */} <MenuItems routes={mainRoutes} isMainMenu={true} /> {/* /z路径二级子菜单 */} <MenuItems routes={subRoutes} />
3. 修正路由定义的语法错误
你现有subRoutes的path写错了,把正则格式改为字符串格式:
const subRoutes = [ { path: '/z/a', name: 'z a', component: ..., }, { path: '/z/b', name: 'z b', component: ..., }, { path: '/z/c', name: 'z c', component: ..., } ];
扩展说明
如果后续有多层嵌套路由的需求,可以给每个路由配置项增加parentPath字段,匹配逻辑会更灵活,避免前缀匹配出现冲突的情况。
内容的提问来源于stack exchange,提问作者JavaScripter
相关产品推荐
相关产品推荐

