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

React侧边栏动态激活菜单颜色切换异常求助

侧边栏菜单点击动态切换颜色失效问题

我在实现侧边栏菜单点击时动态切换颜色功能时遇到问题:当用户从/building页面切换到/street页面,点击“street”菜单后,希望该菜单能像激活状态的“building”菜单一样变为红色,但实际效果不符合预期。以下是Sidebar.jsx代码及效果截图。

原代码

import React from "react";
import { useState } from "react";
import { BiBuildingHouse } from "react-icons/bi";
import { FaRoad } from "react-icons/fa";
import { Link, NavLink } from "react-router-dom";

const Sidebar = () => {
  const [activeMenu, setActiveMenu] = useState(false);

  return (
    <div className='w-[16rem] h-[72rem] bg-[#FFFFFF] px-5 py-3 md:px-8 md:py-5 drop-shadow-xl"' >
      <h1 className="text-[#92929D] font-semibold ml-3">DASHBOARD</h1>

      <NavLink
        to="/try/building"
        className={
          activeMenu === "/try/building"
            ? "mr-6 mt-4 w-[12rem] h-[4rem] bg-red-500 text-white py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
            : "mr-6 mt-4 text-black py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
        }
        onClick={() => {
          setActiveMenu("/try/building");
        }}
        active={activeMenu}
      >
        <div className="mr-6 mt-4 w-[12rem] h-[4rem] bg-red-500 py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer">
          <div className="inline-flex gap-4 items-center">
            <BiBuildingHouse size={25} className="text-white" />
            <h1 className="text-white">Building</h1>
          </div>
        </div>
      </NavLink>

      <Link
        to="/try/street"
        className={
          activeMenu === "/try/street"
            ? "mr-6 mt-4 w-[12rem] h-[4rem] bg-red-500 text-white py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
            : "mr-6 mt-4 text-black py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
        }
        onClick={() => {
          setActiveMenu("/try/street");
        }}
        active={activeMenu}
      >
        <div className="mr-6 w-[12rem] h-[4rem] py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer">
          <div className="inline-flex gap-4 items-center">
            <FaRoad size={25} className="text-[#92929D]" />
            <h1 className="text-black">Street</h1>
          </div>
        </div>
      </Link>
    </div>
  );
};

export default Sidebar;

效果截图

效果截图1
效果截图2


问题分析

  1. 内部div固定样式覆盖父级状态:Building菜单的NavLink里嵌套了硬写bg-red-500的div,不管父级NavLink状态怎么变,这个div都会显示红色;Street菜单内部的div固定了非激活样式,即使外层Link的className切换,内部元素颜色也不会变化,导致点击后看不到红色效果。
  2. 手动状态与NavLink原生功能冲突:NavLink本身自带路由激活状态判断,手动维护activeMenu的同时混用NavLink,逻辑混乱,且初始值false和后续赋值的路由字符串类型不匹配,可能导致判断失效。
  3. 混用NavLink和Link:Street菜单用了普通Link,没有激活状态判断能力,应该统一使用NavLink。

修复代码

import React from "react";
import { BiBuildingHouse } from "react-icons/bi";
import { FaRoad } from "react-icons/fa";
import { NavLink } from "react-router-dom";

const Sidebar = () => {
  return (
    <div className='w-[16rem] h-[72rem] bg-[#FFFFFF] px-5 py-3 md:px-8 md:py-5 drop-shadow-xl'>
      <h1 className="text-[#92929D] font-semibold ml-3">DASHBOARD</h1>

      <NavLink
        to="/try/building"
        className={({ isActive }) => 
          `mr-6 mt-4 w-[12rem] h-[4rem] py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer ${
            isActive ? "bg-red-500 text-white" : "text-black"
          }`
        }
      >
        <div className="inline-flex gap-4 items-center h-full">
          <BiBuildingHouse size={25} className={({ isActive }) => isActive ? "text-white" : "text-[#92929D]"} />
          <h1>Building</h1>
        </div>
      </NavLink>

      <NavLink
        to="/try/street"
        className={({ isActive }) => 
          `mr-6 mt-4 w-[12rem] h-[4rem] py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer ${
            isActive ? "bg-red-500 text-white" : "text-black"
          }`
        }
      >
        <div className="inline-flex gap-4 items-center h-full">
          <FaRoad size={25} className={({ isActive }) => isActive ? "text-white" : "text-[#92929D]"} />
          <h1>Street</h1>
        </div>
      </NavLink>
    </div>
  );
};

export default Sidebar;

关键修改说明

  • 删掉手动维护的activeMenu状态,改用NavLink自带的isActive参数判断激活状态,这是React Router原生支持的能力,更稳定可靠。
  • 移除内部嵌套的固定样式div,把样式直接写在NavLink上,内部图标和文字的颜色通过父级激活状态动态切换。
  • 统一使用NavLink代替Link,确保两个菜单都能正确识别路由激活状态。
  • 清理了冗余的重复样式,让代码结构更简洁。

内容的提问来源于stack exchange,提问作者Kia Kalista

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:31:18