我使用导航栏作为页面上的组件,它使用路由器来更改内容。到目前为止,一切都运行良好。但我不知道如何在单击导航栏中的链接时将其状态设置为活动状态。我想,我必须将 Nav 元素的 activeKey 绑定到活动内容的 location.pathname 。
这是我的导航栏组件:
import React from 'react';
import { Navbar, Nav } from 'react-bootstrap';
class Navbar extends React.Component{
constructor() {
super();
this.state = {
show: false
};
}
render(){
return(
<div>
<Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
<Navbar.Brand >Filmmusic</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav activeKey="/" className="mr-auto">
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="/about">About</Nav.Link>
<Nav.Link onClick = {()=>{this.handleModal()}}>Contact</Nav.Link>
</Nav>
<Nav>
<Nav.Link href="/impressum">Impressum</Nav.Link>
<Nav.Link href="/datenschutzerklaerung">Datenschutzerklärung</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
</div>
)
}
}
export default Navbar;
非常感谢!现在一切正常:)我将导航栏代码写入index.js,而不是使用组件。我将所有组件都放在 Router 元素下方。这是我的 index.js 的最终代码:
import React from 'react';
import ReactDOM from 'react-dom';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import { Home } from './components/Home';
import { About } from './components/About';
import { Contact } from './components/Contact';
import { NoMatch } from './components/NoMatch';
import { Impressum } from './components/Impressum';
import { Datenschutzerklaerung } from './components/Datenschutzerklaerung';
import { Layout } from './components/Layout';
import { Jumbotron } from './components/Jumbotron';
import Footer from './components/Footer';
import './fontawesome';
import { Navbar, Nav } from "react-bootstrap";
import { withRouter } from "react-router";
const Header = props => {
const { location } = props;
return (
<Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
<Navbar.Brand >Filmmusic</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav activeKey={location.pathname} className="mr-auto">
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="/about">About</Nav.Link>
<Nav.Link href="/contact">Contact</Nav.Link>
</Nav>
<Nav activeKey={location.pathname}>
<Nav.Link href="/impressum">Impressum</Nav.Link>
<Nav.Link href="/datenschutzerklaerung">Datenschutzerklärung</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
);
};
const HeaderWithRouter = withRouter(Header);
class MyHeader extends React.Component {
render() {
return (
<React.Fragment>
<Router>
<HeaderWithRouter />
<Jumbotron />
<Switch>
<Route exact path="/" component={Home} />
<Layout>
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<Route path="/impressum" component={Impressum} />
<Route path="/datenschutzerklaerung" component={Datenschutzerklaerung} />
</Layout>
<Route component={NoMatch} />
</Switch>
</Router>
<Footer />
</React.Fragment>
);
}
}
ReactDOM.render(<MyHeader />, document.getElementById('root'));
如果你不想使用路由器并且需要更灵活地改变状态,你也可以使用
useState
钩子:
export const Nav = () => {
const [active, setActive] = useState('default');
return (
<>
<Nav
className="sub-nav"
activeKey={active}
onSelect={(selectedKey) => setActive(selectedKey)}
>
<Nav.Item>
<Nav.Link eventKey="default">Default</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="link-1">Link 1</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="link-2">Link 2</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="disabled" disabled>
Disabled
</Nav.Link>
</Nav.Item>
</Nav>
</>
);
};
您必须使用
NavBar
HOC 包装您的 withRouter
组件。然后您可以进行以下更改:
render(){
const { location } = props; //add this
return(
<div>
<Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
<Navbar.Brand >Filmmusic</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav activeKey={location.pathname} className="mr-auto"> //Update this
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="/about">About</Nav.Link>
<Nav.Link onClick = {()=>{this.handleModal()}}>Contact</Nav.Link>
<Nav.Link href="/impressum">Impressum</Nav.Link>
<Nav.Link href="/datenschutzerklaerung">Datenschutzerklärung</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
</div>
)
}
有关 withRouter HOC 的更多详细信息。
withRouter
v5.1起已弃用
react-router
所以你可以只使用位置钩子。
const location = useLocation();
...
<Nav activeKey={location.pathname} className="mr-auto">
...
我必须混合使用两者
as={Link} to{"/" href="#"
才能使活跃风格发挥作用:
<Nav.Link as={Link} to={"/"} href="#">
<span className={styles.ddlink}><FontAwesomeIcon icon={myIcons['house']} fontSize="1.0rem" /> HOME</span>
</Nav.Link>
<Nav.Link as={Link} to={"/resume"} href="#resume">
<span className={styles.ddlink}><FontAwesomeIcon icon={myIcons['book']} fontSize="1.0rem" /> RESUME</span>
</Nav.Link>
您可以遵循以下三个规则:
1.使用useLocation获取活动路径。
2.在Nav组件中使用activeKey={location.pathname}。
const Header = () => {
const location = useLocation();
return (
<Navbar activeKey={location.pathname} collapseOnSelect expand='lg' bg="light" variant="light" className='shadow-sm'>
<Container className='fw-bold '>
<Navbar.Brand className='fs-1' href="#home">Let's Learn</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav" className='lg-d-flex justify-content-end'>
<Nav activeKey={location.pathname}>
<Nav.Link className='me-5' href="/home">Home</Nav.Link>
<Nav.Link className='me-5' href="/blog">Blog</Nav.Link>
<Nav.Link className='me-5' href="/services">Statistics</Nav.Link>
<Nav.Link className='me-5' href="/about">About</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
);
}
3.在 CSS 文件中写入活动颜色,例如:
.active{
color: blue!important;
}
我已经尝试了上面的所有解决方案,但要么需要降级
react-router
,要么由于重新渲染而不起作用,最后我找到了完美的解决方案,不需要对当前代码进行任何更改,只需使用window.location.pathname
。
<Nav activeKey={window.location.pathname}>
// <Nav.Link href="/">Home</Nav.Link>
</Nav>
那么,干杯!