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;
效果截图


问题分析
- 内部div固定样式覆盖父级状态:Building菜单的NavLink里嵌套了硬写
bg-red-500的div,不管父级NavLink状态怎么变,这个div都会显示红色;Street菜单内部的div固定了非激活样式,即使外层Link的className切换,内部元素颜色也不会变化,导致点击后看不到红色效果。 - 手动状态与NavLink原生功能冲突:NavLink本身自带路由激活状态判断,手动维护
activeMenu的同时混用NavLink,逻辑混乱,且初始值false和后续赋值的路由字符串类型不匹配,可能导致判断失效。 - 混用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
相关产品推荐
相关产品推荐

