You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何从菜单数组传递路由路径并实现点击更新功能?

问题分析与解决方案

核心问题

  1. 菜单状态更新逻辑错误:getMenuPath 函数中使用 map 时,匹配项返回的是 item.path 而非更新后的菜单项对象,导致 menuItems 数组被破坏;同时直接修改原对象属性(item.menuItemState = true)违反 React 状态不可变原则。
  2. 路由组件使用错误:Route 的 component 属性应传入组件引用(如 component={About}),而非 JSX 实例(<About />)。
  3. 缺少首页路由:未在 Switch 中配置根路径 / 的路由规则。
  4. 菜单状态与路由不同步:仅通过点击事件更新状态,无法响应浏览器前进/后退等路由变化。

修复后的完整代码

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;

关键修复点说明

  1. 路由监听与状态同步:使用 useLocation 获取当前路由路径,通过 useEffect 监听路径变化,自动更新对应菜单项的激活状态,确保路由与菜单状态始终一致。
  2. 正确更新状态:采用不可变更新方式(...item 复制原对象)修改 menuItemState,避免直接修改状态对象。
  3. 路由组件修正:将 component={<About />} 改为 component={About},符合 React Router v5 的 API 规范。
  4. 添加首页路由:补充根路径 / 的路由配置,确保首页内容正常显示。

在 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:48:25