React导航实现点击仅为选中链接切换active类控制巨型菜单样式
修复思路与代码实现
问题根因
你当前所有导航项共用同一个布尔类型的active状态,任意菜单点击触发状态变更后,所有导航项都会命中id={active ? 'open' : ''}的判断条件,才会出现全部添加激活标识的问题。
修复方案
我们将状态存储内容从布尔值调整为「当前激活菜单的唯一标识」,只有匹配标识的导航项才会添加激活样式:
- 将
useState初始值设为null,用来存储当前激活菜单的唯一key - 给每个导航菜单定义唯一标识,比如「关于我们」用
about,「解决方案」用solutions - 点击菜单时传入对应标识:如果当前激活标识和传入标识一致就关闭菜单,否则切换为当前点击的菜单
- 每个
Nav.Link仅在自身标识和当前激活标识匹配时,才添加openid或自定义激活类
修改后完整代码
import React, {useState} from "react"; import { Navbar, Nav, Container } from "react-bootstrap"; import { FaArrowRight } from "react-icons/fa"; import Button from "react-bootstrap/Button"; import LogoTransparent from "../../images/logo/logo-reverse.png"; import LogoWhite from "../../images/logo/logo-white.png"; const TransparentNavbar = (props) => { // check if the background is transparent to return corresponding logo. let LogoType; if (props.bgLogo === "transparent") { LogoType = LogoTransparent; } else { LogoType = LogoWhite; } // 状态改为存储当前激活的菜单key,初始为null代表无激活菜单 const [activeMenu, setActiveMenu] = useState(null) return ( <Navbar collapseOnSelect expand={props.bgExpand} bg={props.bgIntrinsic} variant={props.bgVariant} sticky={props.bgSticky} fixed={props.bgFixed} className={props.bgColor} > <Container> <Navbar.Brand className="navbar-brand-margin" href="#home"> <img src={LogoType} className="d-inline-block align-top" alt="" /> </Navbar.Brand> <Navbar.Toggle aria-controls="responsive-navbar-nav" /> <Navbar.Collapse id="responsive-navbar-nav"> <Nav className="ml-auto"> {/* About Us 菜单,唯一标识为about */} <Nav.Link id={activeMenu === 'about' ? 'open' : ''} className={`${props.bgtextColor} ${props.bgExpandBtn} ${activeMenu === 'about' ? 'custom-active' : ''}`} onClick={() => setActiveMenu(activeMenu === 'about' ? null : 'about')} > About Us <div className="mega-menu"> <div className="content"> <div className="col first-col"> <section> <ul className="mega-links expandable"> <a href="/about/company-overview" className="mega-menu-links-white-bg" > <li>Company Overview</li> </a> <a href="/about/partners" className="mega-menu-links-white-bg" > <li>Partners</li> </a> <a href="/about/mission-vision-core-values" className="mega-menu-links-white-bg" > <li>Mission, Vision & Core Values</li> </a> <a href="/about/management-team" className="mega-menu-links-white-bg" > <li>Management Team</li> </a> <a href="/board-of-directors" className="mega-menu-links-white-bg" > <li>Board of Directors</li> </a> </ul> </section> </div> <div className="col second-col"> <section> <div className="mega-menu-text"> <p> We focus on delivering digital solutions to our clients such that high value can be derived with a huge ROI. We have experience and expertise in providing such a digital transformation program to alleviate clients' pain point and position such clients for efficient and effective operation with a high possibility of increasing their revenue and profit at the same time. </p> <div className="mega-menu-button"> <Button variant="outline-primary" className="primary-mega-button shadow-none" > Read More <FaArrowRight /> </Button> </div> </div> </section> </div> <div className="col third-col"> <section> <h5 className="mega-menu-image-header-text"> *** Limited is a leading Africa Technology and Digital Consulting Firm </h5> <a href="#" className="img-wrapper"> <span className="img"> <img className="w-100" src="https://picsum.photos/400?random=1" alt="Random Image" /> </span> </a> </section> </div> </div> </div> </Nav.Link> {/* Solutions 菜单,唯一标识为solutions */} <Nav.Link id={activeMenu === 'solutions' ? 'open' : ''} className={`${props.bgtextColor} ${props.bgExpandBtn} ${activeMenu === 'solutions' ? 'custom-active' : ''}`} onClick={() => setActiveMenu(activeMenu === 'solutions' ? null : 'solutions')} > Solutions <div className="mega-menu"> <div className="content"> <div className="col first-col"> <section> <ul className="mega-links expandable"> <a href="/about/company-overview" className="mega-menu-links-white-bg" > <li>Digital Culture</li> </a> <a href="/about/partners" className="mega-menu-links-white-bg" > <li>Identity & Access Management</li> </a> <a href="/about/mission-vision-core-values" className="mega-menu-links-white-bg" > <li>Cyber Security</li> </a> <a href="/about/management-team" className="mega-menu-links-white-bg" > <li>Management Team</li> </a> <a href="/board-of-directors" className="mega-menu-links-white-bg" > <li>DevOps Services</li> </a> </ul> </section> </div> <div className="col second-col-link"> <section> <ul className="mega-links second"> <a href="/about/company-overview" className="mega-menu-links-white-bg" > <li>Managed IT Infrastructure</li> </a> <a href="/about/partners" className="mega-menu-links-white-bg" > <li>Digital Transformation (DX)</li> </a> <a href="/about/mission-vision-core-values" className="mega-menu-links-white-bg" > <li>Technology Consulting & Advisory Service</li> </a> <a href="/about/management-team" className="mega-menu-links-white-bg" > <li>Cloud Computing (Microsoft, SAP) Team</li> </a> </ul> </section> </div> <div className="col third-col"> <section> <h5 className="mega-menu-image-header-text"> is a leading Africa Technology and Digital Consulting Firm </h5> <a href="#" className="img-wrapper"> <span className="img"> <img className="w-100" src="https://picsum.photos/400?random=1" alt="Random Image" /> </span> </a> </section> </div> </div> </div> </Nav.Link> </Nav> </Navbar.Collapse> </Container> </Navbar> ); }; export default TransparentNavbar;
补充说明
- 代码里新增的
custom-active就是你需要的自定义激活类,可以直接根据这个类名写移动端的定制样式 - 后续新增导航菜单只需要定义新的唯一标识,按照现有逻辑仿写即可
- 大屏端的hover触发逻辑不受这个状态影响,原有CSS的hover样式可以正常保留
- 如果需要点击菜单外区域自动关闭菜单,可以额外给document加点击事件监听,判断点击源不在导航区域内就把
activeMenu设为null
内容的提问来源于stack exchange,提问作者Tobi
相关产品推荐
相关产品推荐

