React中如何从菜单数组传递路由路径并实现点击更新功能?
问题分析与解决方案
核心问题
- 菜单状态更新逻辑错误:
getMenuPath函数中使用map时,匹配项返回的是item.path而非更新后的菜单项对象,导致menuItems数组被破坏;同时直接修改原对象属性(item.menuItemState = true)违反 React 状态不可变原则。 - 路由组件使用错误:
Route的component属性应传入组件引用(如component={About}),而非 JSX 实例(<About />)。 - 缺少首页路由:未在
Switch中配置根路径/的路由规则。 - 菜单状态与路由不同步:仅通过点击事件更新状态,无法响应浏览器前进/后退等路由变化。
修复后的完整代码
import React, { useState, useEffect } from 'react' import Menu from './components/Menu' import Logo from './components/Logo' import LeftSide from '../src/components/LeftSide' import About from './components/About' import Projects from './components/Projects' import Contact from './components/Contact' import RightSide from './components/RightSide' import { BrowserRouter as Router, Route, Link, Switch, useLocation } from "react-router-dom"; function App() { const location = useLocation(); const [menuItems, setMenuItems] = useState([ { id: 1, menuItemName: 'Home', path: '/', menuItemState: true }, { id: 2, menuItemName: 'About', path: '/about', menuItemState: false }, { id: 3, menuItemName: 'Projects', path: '/projects', menuItemState: false }, { id: 4, menuItemName: 'Contact', path: '/contact', menuItemState: false } ]) // 监听路由变化,同步更新菜单激活状态 useEffect(() => { setMenuItems(prevItems => prevItems.map(item => ({ ...item, menuItemState: item.path === location.pathname })) ); }, [location.pathname]); return ( <Router> <div className="App"> <div className="relative flex lg:flex-row space-y-0 md:flex-col flex-col h-screen"> <div className="flex flex-col space-y-24 md:space-y-30 lg:space-y-56 p-4 bg-[#1c1c1c] w-full"> <Logo /> <LeftSide /> <div className='flex flex-row p-1'></div> </div> <div className="text-white bg-[#171717] p-4 w-full"> <div className="flex flex-col lg:space-y-36 md:space-y-16 space-y-0 p-1 w-full"> <div className="hidden md:hidden lg:block"> <Menu menuItems={menuItems} /> <Switch> <Route path="/about" exact component={About} /> <Route path="/projects" exact component={Projects} /> <Route path="/contact" exact component={Contact} /> <Route path="/" exact component={/* 替换为你的首页组件 */} /> </Switch> </div> <RightSide /> </div> </div> </div> </div> </Router> ); } export default App;
关键修复点说明
- 路由监听与状态同步:使用
useLocation获取当前路由路径,通过useEffect监听路径变化,自动更新对应菜单项的激活状态,确保路由与菜单状态始终一致。 - 正确更新状态:采用不可变更新方式(
...item复制原对象)修改menuItemState,避免直接修改状态对象。 - 路由组件修正:将
component={<About />}改为component={About},符合 React Router v5 的 API 规范。 - 添加首页路由:补充根路径
/的路由配置,确保首页内容正常显示。
Menu 组件配合修改示例
在 Menu 组件中,应使用 Link 组件生成导航链接,替代自定义点击事件:
import { Link } from 'react-router-dom'; function Menu({ menuItems }) { return ( <nav> {menuItems.map(item => ( <Link key={item.id} to={item.path} className={item.menuItemState ? 'active-menu-item' : ''} > {item.menuItemName} </Link> ))} </nav> ); } export default Menu;
内容的提问来源于stack exchange,提问作者Abdurehman Saleemi
相关产品推荐
相关产品推荐

