React Bootstrap Nav.Link仅第二次点击显示激活状态如何解决
问题原因
- 你的
NavBar组件当前没有放在Router的公共渲染区域,大概率是在每个路由对应的页面组件内单独引入,路由切换时整个NavBar会重新挂载,导致首次点击时激活状态还没同步到新渲染的NavBar上 - react-bootstrap的
Nav.Link默认不会自动同步react-router的路由状态作为激活判定依据,需要手动绑定激活状态
修复步骤
步骤1:调整App.js结构,把NavBar放到Router公共区域
你现在的App.js里只渲染了Switch里的路由内容,没有公共的导航栏,把NavBar移到Router下、Switch外,这样路由切换时NavBar不会重新挂载:
// App.js 新增导入NavBar import NavBar from './components/NavBar' // 修改return部分结构 return ( <Router> {/* 登录页不需要导航栏可以加判断逻辑 */} {user && <NavBar />} <Switch> {/* 原有路由规则保持不变 */} <Route path="/login"> <Login /> </Route> <Route path="/dashboard"> <Dashboard /> </Route> <Route path="/competitions"> <ManageCompetitions /> </Route> <Route path="/tracks"> <ManageTracks /> </Route> <Route path="/"> {user ? <Redirect to="/dashboard" /> : <Redirect to="/login" />} </Route> </Switch> </Router> )
修改完成后删掉各个页面组件(Dashboard、ManageCompetitions等)里单独引入的NavBar代码,避免重复渲染。
步骤2:给Nav.Link绑定动态激活状态
用react-router的useLocation钩子获取当前路径,和Nav.Link的to属性对比,手动设置active属性:
// NavBar.js 新增导入useLocation import { Link, useLocation } from 'react-router-dom' const NavBar = () => { const currentLanguage = useSelector((state) => state) const location = useLocation() // 获取当前路由路径 if(!currentLanguage) { return null } const code = currentLanguage.code return ( <div> <Navbar collapseOnSelect expand="lg" bg="dark" variant="dark"> <Container> <Navbar.Toggle aria-controls="responsive-navbar-nav" /> <Navbar.Collapse id="responsive-navbar-nav"> <Nav className="mr-auto"> <Nav.Link as={Link} to="/dashboard" active={location.pathname === '/dashboard'} > {text[code]['dashboard']} </Nav.Link> <Nav.Link as={Link} to="/competitions" active={location.pathname === '/competitions'} > {text[code]['competitions']} </Nav.Link> <Nav.Link as={Link} to="/tracks" active={location.pathname === '/tracks'} > {text[code]['tracks']} </Nav.Link> </Nav> </Navbar.Collapse> <LanguageSwitchSelector /> <Logout text={text[code]['logout']} /> </Container> </Navbar> </div> ) }
可选替代方案
你也可以直接把as属性的值换成react-router的NavLink组件,NavLink会自动根据当前路径添加active类,只要和react-bootstrap的激活类名匹配就可以自动生效,不需要手动判断路径:
// NavBar.js 导入NavLink import { NavLink } from 'react-router-dom' // 修改Nav.Link的as属性,加exact避免路径前缀匹配错误 <Nav.Link as={NavLink} exact to="/dashboard"> {text[code]['dashboard']} </Nav.Link>
内容的提问来源于stack exchange,提问作者Matthew Everitt
相关产品推荐
相关产品推荐

