react-sidebar-pro侧边栏菜单项active状态需刷新才更新如何解决
问题原因
你当前的代码直接读取原生
window.location.pathname做active判断,该属性不属于React的响应式状态,路由切换时不会触发Sidebar组件重渲染,因此只有刷新页面重新执行组件逻辑时,active状态才会更新。
解决方案
你的代码已用到Link组件,默认使用react-router路由库,核心是用react-router提供的响应式路由钩子useLocation获取路径,路径变化时会自动触发组件重渲染,实时计算active状态。
步骤1:导入useLocation
在Sidebar.js顶部引入useLocation:
import { useLocation, Link } from 'react-router-dom'
步骤2:在组件内调用钩子获取当前路径
在Sidebar函数内部新增一行代码:
const location = useLocation()
步骤3:替换所有路径判断逻辑
把所有active属性判断里的window.location.pathname替换成location.pathname即可。
修改后的完整代码
import { useState } from 'react' import { useLocation, Link } from 'react-router-dom' import { ProSidebar, SidebarHeader, SidebarContent, SidebarFooter, Menu, MenuItem } from 'react-sidebar-pro' import { FiArrowRightCircle, FiArrowLeftCircle, FiHome, FiLogOut } from 'react-icons/fi' import { FaList } from 'react-icons/fa' import { RiPencilLine } from 'react-icons/ri' function Sidebar() { const [menuCollapse, setMenuCollapse] = useState(false) const location = useLocation() // 新增响应式路径获取 const menuIconClick = () => { setMenuCollapse(!menuCollapse) } return ( <> <div id="header"> <ProSidebar collapsed={menuCollapse}> <SidebarHeader> <div className="logotext"> <p>{menuCollapse ? "LOGO" : "LONG LOGO"}</p> </div> <div className="closemenu" onClick={menuIconClick}> {menuCollapse ? ( <FiArrowRightCircle/> ) : ( <FiArrowLeftCircle/> )} </div> </SidebarHeader> <SidebarContent> <Menu iconShape="square"> {/* 替换为响应式的location.pathname判断 */} <MenuItem active={location.pathname === "/"} icon={<FiHome />} > Home <Link to="/"/> </MenuItem> <MenuItem active={location.pathname === "/FAQ"} icon={<FaList />}> FAQ <Link to="/FAQ"/> </MenuItem> <MenuItem active={location.pathname === "/Search-sec"} icon={<RiPencilLine />}> SEARCH SEC <Link to="/Search-sec"/> </MenuItem> </Menu> </SidebarContent> <SidebarFooter> <Menu iconShape="square"> <MenuItem icon={<FiLogOut />}>Logout</MenuItem> </Menu> </SidebarFooter> </ProSidebar> </div> </> ) } export default Sidebar
可选优化
可以把菜单项抽成配置数组,后续新增菜单不需要重复写判断逻辑,同时可以给MenuItem指定component属性,点击任意位置即可跳转,体验更好:
// 菜单配置 const menuItems = [ { path: '/', name: 'Home', icon: <FiHome /> }, { path: '/FAQ', name: 'FAQ', icon: <FaList /> }, { path: '/Search-sec', name: 'SEARCH SEC', icon: <RiPencilLine /> } ] // 渲染时直接遍历 <Menu iconShape="square"> {menuItems.map(item => ( <MenuItem key={item.path} active={location.pathname === item.path} icon={item.icon} component={Link} // 直接指定MenuItem渲染为Link to={item.path} > {item.name} </MenuItem> ))} </Menu>
内容的提问来源于stack exchange,提问作者mirkovski
相关产品推荐
相关产品推荐

