如何从 React Router 添加活动 class 到 Link?
How do I add an active class to a Link from React Router?
我使用 Link
创建了一个 bootstrap 风格的边栏。这是我的代码片段:
<ul className="sidebar-menu">
<li className="header">MAIN NAVIGATION</li>
<li><Link to="dashboard"><i className="fa fa-dashboard"></i> <span>Dashboard</span></Link></li>
<li><Link to="email_lists"><i className="fa fa-envelope-o"></i> <span>Email Lists</span></Link></li>
<li><Link to="billing"><i className="fa fa-credit-card"></i> <span>Buy Verifications</span></Link></li>
</ul>
我想在包装元素 <li>
上将活动路径的 class 设置为 active
。我看到还有其他解决方案展示了如何像 那样执行此操作,但是我认为这不是将包装器上的活动 class 设置为 Link
的最佳方法].
我也找到了https://github.com/insin/react-router-active-component但是感觉没有必要
在 React Router 中,这是可能的还是我需要使用外部解决方案?
在 Link 组件上,您现在可以添加 activeClassName 或设置 activeStyle.
这些使您可以轻松地向当前活动的 link 添加样式。
以前,您可以使用以下逻辑创建一个像 Link 的包装器一样工作的自定义组件。
在名为 nav_link.js
的文件中
import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
class NavLink extends React.Component {
render() {
var isActive = this.context.router.route.location.pathname === this.props.to;
var className = isActive ? 'active' : '';
return(
<Link className={className} {...this.props}>
{this.props.children}
</Link>
);
}
}
NavLink.contextTypes = {
router: PropTypes.object
};
export default NavLink;
并在您的组件中按以下方式使用它:
...
import NavLink from "./nav_link";
.....
<nav>
<ul className="nav nav-pills pull-right">
<NavLink to="/">
<i className="glyphicon glyphicon-home"></i> <span>Home</span>
</NavLink>
<NavLink to="about">
<i className="glyphicon glyphicon-camera"></i> <span>About</span>
</NavLink>
</ul>
</nav>
答案更新为 ES6:
import React, { Component } from 'react';
import { Link } from 'react-router'
class NavLink extends Component {
render() {
let isActive = this.context.router.isActive(this.props.to, true);
let className = isActive ? "active" : "";
return (
<li className={className}>
<Link {...this.props}/>
</li>
);
}
}
NavLink.contextTypes = {
router: React.PropTypes.object
};
export default NavLink;
然后按上述方法使用它。
我不喜欢创建自定义组件的想法,因为如果您有不同的包装元素,您将不得不创建另一个自定义组件等。而且,这也太过分了。所以我只是用 css 和 activeClassName:
<li className="link-wrapper"> <!-- add a class to the wrapper -->
<Link to="something" activeClassName="active">Something</Link>
</li>
然后再添加一些 css:
li.link-wrapper > a.active {
display: block;
width: 100%;
height:100%;
color: white;
background-color: blue;
}
从技术上讲,这不会为 li 设置样式,但它会使锚点填充 li 并为其设置样式。
这是我的方式,使用道具中的位置。
我不知道,但 history.isActive 对我来说是未定义的
export default class Navbar extends React.Component {
render(){
const { location } = this.props;
const homeClass = location.pathname === "/" ? "active" : "";
const aboutClass = location.pathname.match(/^\/about/) ? "active" : "";
const contactClass = location.pathname.match(/^\/contact/) ? "active" : "";
return (
<div>
<ul className="nav navbar-nav navbar-right">
<li className={homeClass}><Link to="/">Home</Link></li>
<li className={aboutClass}><Link to="about" activeClassName="active">About</Link></li>
<li className={contactClass}><Link to="contact" activeClassName="active">Contact</Link></li>
</ul>
</div>
);}}
你实际上可以复制里面的东西 NavLink 像这样
const NavLink = ( {
to,
exact,
children
} ) => {
const navLink = ({match}) => {
return (
<li class={{active: match}}>
<Link to={to}>
{children}
</Link>
</li>
)
}
return (
<Route
path={typeof to === 'object' ? to.pathname : to}
exact={exact}
strict={false}
children={navLink}
/>
)
}
只需查看 NavLink 源代码并删除不需要的部分 ;)
React-Router V4 附带一个开箱即用的 NavLink 组件
要使用,只需将 activeClassName
属性设置为您已适当设置样式的 class,或直接将 activeStyle
设置为您想要的样式。有关详细信息,请参阅 the docs。
<NavLink
to="/hello"
activeClassName="active"
>Hello</NavLink>
当您使用 react-redux 进行状态管理并且一些父组件是 [= 时,Vijey 的回答有点问题34=] 到 redux 存储。 activeClassName仅在页面刷新时应用到Link,不会随着当前路由的变化而动态应用
这与 react-redux 的连接功能有关,因为它抑制了上下文更新。要禁用抑制上下文更新,您可以在调用 connect()
方法时设置 pure: false
,如下所示:
//your component which has the custom NavLink as its child.
//(this component may be the any component from the list of
//parents and grandparents) eg., header
function mapStateToProps(state) {
return { someprops: state.someprops }
}
export default connect(mapStateToProps, null, null, {
pure: false
})(Header);
检查这里的问题:reactjs#470
在此处查看 pure: false
文档:docs
使用 react-router-dom@4.3.1
(尽管我猜任何 4.x.x
都应该),我们可以使用 withRouter
HOC 来完成此操作。例如,我想实现 Bootstrap 导航栏,因为它需要 <li class="nav-item">
而不是锚标记上的 class 或 active
,我制作了一个名为 NavItem
封装单个li.nav-item
。实现如下:
import React from "react";
import { Link, withRouter } from "react-router-dom";
const NavItem = ({ isActive, to, label }) => {
let classes = ["nav-item"];
if (isActive) classes.push("active");
return (
<li className={classes.join(" ")}>
<Link className="nav-link" to={to}>
{label}
</Link>
</li>
);
};
export default withRouter(({ location, ...props }) => {
const isActive = location.pathname === props.to;
console.log(location.pathname, props.to);
return <NavItem {...props} isActive={isActive} />;
});
如您所见,NavItem
只是一个无状态功能组件,它需要一个 isActive
属性来确定是否应添加 active
class。现在,要随着位置的变化更新这个道具,我们可以使用 withRouter
HOC。您可以将任何组件传递给此函数,它会在其道具中为它提供 { match, location, history }
个对象以及您传递的对象。在这里,我正在创建一个内联功能组件,它接收这些对象并使用 location.pathname
属性 确定当前 link 是否是活动的。这将为我们提供 Boolean
,我们可以 return 将 NavItem
和 isActive
设置为我们使用 location.pathname
.
计算的值
可以找到一个这样的工作示例 here。如果有更简单的方法,请告诉我。
从 react-router-dom@4.3.1 开始,我们可以轻松地使用带有 activeClassName 的 NavLink 而不是 Link。示例:
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
class NavBar extends Component {
render() {
return (
<div className="navbar">
<ul>
<li><NavLink to='/1' activeClassName="active">1</NavLink></li>
<li><NavLink to='/2' activeClassName="active">2</NavLink></li>
<li><NavLink to='/3' activeClassName="active">3</NavLink></li>
</ul>
</div>
);
}
}
然后在您的 CSS 文件中:
.navbar li>.active {
font-weight: bold;
}
NavLink 将根据当前 URL.
将您的自定义样式属性添加到呈现的元素中
文件是here
在活动导航元素上设置 class
import { NavLink } from 'react-router-dom';
&
<NavLink to="/Home" activeClassName="active">Home</NavLink>
这很容易做到,react-router-dom提供了所有。
import React from 'react';
import { matchPath, withRouter } from 'react-router';
class NavBar extends React.Component {
render(){
return(
<ul className="sidebar-menu">
<li className="header">MAIN NAVIGATION</li>
<li className={matchPath(this.props.location.pathname, { path: "/dashboard" }) ? 'active' : ''}><Link to="dashboard"><i className="fa fa-dashboard"></i>
<span>Dashboard</span></Link></li>
<li className={matchPath(this.props.location.pathname, { path: "/email_lists" }) ? 'active' : ''}><Link to="email_lists"><i className="fa fa-envelope-o"></i>
<span>Email Lists</span></Link></li>
<li className={matchPath(this.props.location.pathname, { path: "/billing" }) ? 'active' : ''}><Link to="billing"><i className="fa fa-credit-card"></i>
<span>Buy Verifications</span></Link></li>
</ul>
)
}
}
export default withRouter(NavBar);
使用 withRouter() HOC 包装您的导航组件将为您的组件提供一些道具:
1.匹配
2. 历史
3. 地点
这里我使用了 react-router 中的 matchPath() 方法来比较路径并决定 'li' 标签是否应该得到 "active" class 名字与否。我正在从 this.props.location.pathname.
访问该位置
当我们的 link 被点击时,道具中的路径名称会发生变化,位置道具将得到更新 NavBar 也会得到 re-rendered 并且活动样式将得到应用
从路由器 v4 开始,我使用 'refs' 来设置父活动 class:
<ul>
<li>
<NavLink
innerRef={setParentAsActive}
activeClassName="is-active"
to={link}
>
{text}
</NavLink>
</ul>
NavLink
的 innerRef
属性接受回调函数,它将接收 DOM 节点作为参数。您可以使用任何可能的 DOM 操作,在这种情况下只需将父元素 (<li>
) 设置为具有相同的 class:
const setParentAsActive = node => {
if (node) {
node.parentNode.className = node.className;
}
};
缺点:
<a>
将有不必要的 is-active
class(因为你只需要 <li>
),或者你可以在回调中删除这个 class功能
- 如果更改元素结构,f.e。将
a
标记包裹在 span
中,您的回调将停止工作,但可以编写更复杂的 DOM 遍历函数
- 你必须做一些DOM操作
只需使用 NavLink
而不是 Link
。它会自动添加.active
class。
<Nav className="mr-auto">
<Nav.Link as={NavLink} to="/home">Home</Nav.Link>
<Nav.Link as={NavLink} to="/users">Users</Nav.Link>
</Nav>
扩展@BaiJiFeiLong的回答,在link中添加一个active={}
属性:
<Nav.Link as={Link} to="/user" active={pathname.startsWith('/user')}>User</Nav.Link>
当任何路径以“/user”开头时,这将显示 User
link 处于活动状态。为了在每次路径更改时更新,请在组件上包含 withRouter()
:
import React from 'react'
import { Link, withRouter } from 'react-router-dom'
import Navbar from 'react-bootstrap/Navbar'
import Nav from 'react-bootstrap/Nav'
function Header(props) {
const pathname = props.location.pathname
return (
<Navbar variant="dark" expand="sm" bg="black">
<Navbar.Brand as={Link} to="/">
Brand name
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link as={Link} to="/user" active={pathname.startsWith('/user')}>User</Nav.Link>
<Nav.Link as={Link} to="/about" active={pathname.startsWith('/about')}>About</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
)
}
export default withRouter(Header) // updates on every new page
使用 Jquery 进行活动 link:
$(function(){
$('#nav a').filter(function() {
return this.href==location.href
})
.parent().addClass('active').siblings().removeClass('active')
$('#nav a').click(function(){
$(this).parent().addClass('active').siblings().removeClass('active')
})
});
使用Jquery中指定的组件生命周期方法或文档就绪函数。
import React from 'react';
import {withRouter, Link} from "react-router-dom";
const SidenavItems = (props) => {
// create simple list of links
const items = [
{
type: "navItem",
icon: "home",
text: "Home",
link: "/",
restricted: false
},
{
type: "navItem",
icon: "user-circle",
text: "My Profile",
link: "/user",
restricted: false
},
{
type: "navItem",
icon: "sign-in",
text: "Login",
link: "/login",
restricted: false
},
];
const element = (item, i) => { // create elements (Links)
// check if this is a current link on browser
let active = "";
if (props.location.pathname === item.link) {
active = "active";
}
return (
<div key={i} className={item.type}>
<Link
to={item.link}
className={active} // className will be set to "active"
> // or ""
{item.text}
</Link>
</div>
)
};
const showItems = () => { // print elements
return items.map((item, i) => {
return element(item, i)
})
};
return (
<div>
{showItems()} // print all the links we created in list
</div>
)
};
export default withRouter(SidenavItems);
其中一种使用方式
当您使用功能组件时,请按照此处的说明进行操作。
- 在您的组件中添加一个变量
- 创建事件更改浏览器URLchange/or其他更改
- 重新分配当前路径(URL)
- 使用javascript匹配函数并设置为active或其他
这里使用上面的代码。
import React, { useEffect } from 'react';
import { Link } from 'react-router-dom';
const NavItems = () => {
let pathname = window.location.pathname;
useEffect(() => {
pathname = window.location.pathname;
}, [window.location.pathname]);
return (
<>
<li className="px-4">
<Link to="/home" className={`${pathname.match('/home') ? 'link-active' : ''}`}>Home</Link>
</li>
<li className="px-4">
<Link to="/about-me" className={`${pathname.match('/about-me') ? 'link-active' : ''}`}>About-me</Link>
</li>
<li className="px-4">
<Link to="/skill" className={`${pathname.match('/skill') ? 'link-active' : ''}`}>Skill</Link>
</li>
<li className="px-4">
<Link to="/protfolio" className={`${pathname.match('/protfolio') ? 'link-active' : ''}`}>Protfolio</Link>
</li>
<li className="pl-4">
<Link to="/contact" className={`${pathname.match('/contact') ? 'link-active' : ''}`}>Contact</Link>
</li>
</>
);
}
export default NavItems;
--- 谢谢 ---
当前 React Router 版本 5.2.0
activeStyle 是 NavLink 组件的 默认 css 属性 从 react-router-dom
这样我们就可以编写自己的自定义 css 以使其成为 active.In 这个例子我将背景设为透明并且文本设为 bold.And 我将其存储在名为 [=] 的常量中17=]有效
import React from "react";
import { NavLink} from "react-router-dom";
function nav() {
const isActive = {
fontWeight: "bold",
backgroundColor: "rgba(255, 255, 255, 0.1)",
};
return (
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<NavLink className="nav-link" to="/Shop" activeStyle={isActive}>
Shop
</NavLink>
</li>
</ul>
);
export default nav;
使用 React Hooks。
import React, { useState } from 'react';
export const Table = () => {
const [activeMenu, setActiveMenu] = useState('transaction');
return(
<>
<Link className="flex-1 mr-2">
<a
id="transaction"
className={
activeMenu == 'transaction'
? 'text-center block border border-blue-500 rounded py-2 px-4 bg-blue-500 hover:bg-blue-700 text-white'
: 'text-center block border border-white rounded hover:border-gray-200 text-blue-500 hover:bg-gray-200 py-2 px-4'
}
href="#"
onClick={() => {
setActiveMenu('transaction');
}}>
Recent Transactions
</a>
</Link>
<Link className="flex-1 mr-2">
<a
id="account"
className={
activeMenu == 'account'
? 'text-center block border border-blue-500 rounded py-2 px-4 bg-blue-500 hover:bg-blue-700 text-white'
: 'text-center block border border-white rounded hover:border-gray-200 text-blue-500 hover:bg-gray-200 py-2 px-4'
}
href="#"
onClick={() => {
setActiveMenu('account');
}}>
Account Statement
</a>
</LInk>
</>
)
}
对我来说有用的是使用 NavLink,因为它有这个活动 class 属性.
先导入
import { NavLink } from 'react-router-dom';
使用 activeClassName 获取活动 class 属性.
<NavLink to="/" activeClassName="active">
Home
</NavLink>
<NavLink to="/store" activeClassName="active">
Store
</NavLink>
<NavLink to="/about" activeClassName="active">
About Us
</NavLink>
在 css 中设置您的 class 样式由 属性 激活。
.active{
color:#fcfcfc;
}
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand>
<Nav.Link as="{NavLink}" to="/">Brand Name</Nav.Link>
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<nav className="me-auto">
<Nav.Link as="{NavLink}" to="/" exact>Home</Nav.Link>
<Nav.Link as="{NavLink}" to="/about">About</Nav.Link>
<Nav.Link as="{NavLink}" to="/contact">Contact</Nav.Link>
<NavDropdown title="Dropdown" id="basic-nav-dropdown">
<Nav.Link as="{NavLink}" to="/page1">Dropdown Link 1</Nav.Link>
<Nav.Link as="{NavLink}" to="/page2">Dropdown Link 2</Nav.Link>
<Nav.Link as="{NavLink}" to="/page3">Dropdown Link 3</Nav.Link>
</NavDropdown>
</nav>
</Navbar.Collapse>
</Container>
在 react-router-dom 文档中,您使用 navlink 而不是 link。
https://v5.reactrouter.com/web/api/NavLink
import { NavLink } from "react-router-dom";
<Nav>
<NavLink exact activeClassName="active--link" to="/" className="your class" > Home </NavLink>
<NavLink exact to="/classes" activeClassName="active--link" className="your class" > Classes </NavLink>
</Nav>
<NavLink to="/hello" activeClassName="active">Hello</NavLink>
React Router v6:
来源:Active NavLink 类 与 React Router
您需要使用 className
属性,它现在接受一个函数并传递一个 isActive
布尔值 属性:
<NavLink
to="users"
className={({ isActive }) => (isActive ? 'active' : 'inactive')}
>
Users
</NavLink>
这也非常适合添加多个 类,并且是 v6 beta 中的重大更改:
<NavLink
to="users"
className={({ isActive }) =>
isActive ? 'bg-green-500 font-bold' : 'bg-red-500 font-thin'
}
>
Users
</NavLink>
阅读更多内容并进行现场演示:Active NavLink 类 with React Router
<NavLink to='/' activeClassName='active'>
Home
</NavLink>
我只是使用了 NavLink
和 activeClassName
而没有将其包装在任何组件或其他东西中,但我的代码仍然有效:)
在 React 路由器版本 6 中,我们通过 NavLink 完成它并设置它的类名 属性。
我们在这里指定了一个函数,每次路由更改时都会调用该函数。
import { NavLink } from 'react-router-dom';
import classes from './MainHeader.module.css';
const MainHeader = () => {
return (
<header className={classes.header}>
<nav>
<ul>
<li>
<NavLink className={({isActive}) => isActive ? classes.active : ''} to='/welcome'>
Welcome
</NavLink>
</li>
<li>
<NavLink className={({isActive}) => isActive ? classes.active : ''} to='/products'>
Products
</NavLink>
</li>
</ul>
</nav>
</header>
);
};
export default MainHeader;
È=12=ÈтÈ=13=Èт@вшш=11=Èт
w=10=sh
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
class NavBar extends Component {
render() {
return (
<div className="navbar">
<ul>
<li><NavLink to='/1' activeClassName="active">1</NavLink></li>
<li><NavLink to='/2' activeClassName="active">2</NavLink></li>
<li><NavLink to='/3' activeClassName="active">3</NavLink></li>
</ul>
</div>
);
}
}
这适用于我的...
我使用 Link
创建了一个 bootstrap 风格的边栏。这是我的代码片段:
<ul className="sidebar-menu">
<li className="header">MAIN NAVIGATION</li>
<li><Link to="dashboard"><i className="fa fa-dashboard"></i> <span>Dashboard</span></Link></li>
<li><Link to="email_lists"><i className="fa fa-envelope-o"></i> <span>Email Lists</span></Link></li>
<li><Link to="billing"><i className="fa fa-credit-card"></i> <span>Buy Verifications</span></Link></li>
</ul>
我想在包装元素 <li>
上将活动路径的 class 设置为 active
。我看到还有其他解决方案展示了如何像 Link
的最佳方法].
我也找到了https://github.com/insin/react-router-active-component但是感觉没有必要
在 React Router 中,这是可能的还是我需要使用外部解决方案?
在 Link 组件上,您现在可以添加 activeClassName 或设置 activeStyle.
这些使您可以轻松地向当前活动的 link 添加样式。
以前,您可以使用以下逻辑创建一个像 Link 的包装器一样工作的自定义组件。
在名为 nav_link.js
的文件中import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
class NavLink extends React.Component {
render() {
var isActive = this.context.router.route.location.pathname === this.props.to;
var className = isActive ? 'active' : '';
return(
<Link className={className} {...this.props}>
{this.props.children}
</Link>
);
}
}
NavLink.contextTypes = {
router: PropTypes.object
};
export default NavLink;
并在您的组件中按以下方式使用它:
...
import NavLink from "./nav_link";
.....
<nav>
<ul className="nav nav-pills pull-right">
<NavLink to="/">
<i className="glyphicon glyphicon-home"></i> <span>Home</span>
</NavLink>
<NavLink to="about">
<i className="glyphicon glyphicon-camera"></i> <span>About</span>
</NavLink>
</ul>
</nav>
答案更新为 ES6:
import React, { Component } from 'react';
import { Link } from 'react-router'
class NavLink extends Component {
render() {
let isActive = this.context.router.isActive(this.props.to, true);
let className = isActive ? "active" : "";
return (
<li className={className}>
<Link {...this.props}/>
</li>
);
}
}
NavLink.contextTypes = {
router: React.PropTypes.object
};
export default NavLink;
然后按上述方法使用它。
我不喜欢创建自定义组件的想法,因为如果您有不同的包装元素,您将不得不创建另一个自定义组件等。而且,这也太过分了。所以我只是用 css 和 activeClassName:
<li className="link-wrapper"> <!-- add a class to the wrapper -->
<Link to="something" activeClassName="active">Something</Link>
</li>
然后再添加一些 css:
li.link-wrapper > a.active {
display: block;
width: 100%;
height:100%;
color: white;
background-color: blue;
}
从技术上讲,这不会为 li 设置样式,但它会使锚点填充 li 并为其设置样式。
这是我的方式,使用道具中的位置。 我不知道,但 history.isActive 对我来说是未定义的
export default class Navbar extends React.Component {
render(){
const { location } = this.props;
const homeClass = location.pathname === "/" ? "active" : "";
const aboutClass = location.pathname.match(/^\/about/) ? "active" : "";
const contactClass = location.pathname.match(/^\/contact/) ? "active" : "";
return (
<div>
<ul className="nav navbar-nav navbar-right">
<li className={homeClass}><Link to="/">Home</Link></li>
<li className={aboutClass}><Link to="about" activeClassName="active">About</Link></li>
<li className={contactClass}><Link to="contact" activeClassName="active">Contact</Link></li>
</ul>
</div>
);}}
你实际上可以复制里面的东西 NavLink 像这样
const NavLink = ( {
to,
exact,
children
} ) => {
const navLink = ({match}) => {
return (
<li class={{active: match}}>
<Link to={to}>
{children}
</Link>
</li>
)
}
return (
<Route
path={typeof to === 'object' ? to.pathname : to}
exact={exact}
strict={false}
children={navLink}
/>
)
}
只需查看 NavLink 源代码并删除不需要的部分 ;)
React-Router V4 附带一个开箱即用的 NavLink 组件
要使用,只需将 activeClassName
属性设置为您已适当设置样式的 class,或直接将 activeStyle
设置为您想要的样式。有关详细信息,请参阅 the docs。
<NavLink
to="/hello"
activeClassName="active"
>Hello</NavLink>
当您使用 react-redux 进行状态管理并且一些父组件是 [= 时,Vijey 的回答有点问题34=] 到 redux 存储。 activeClassName仅在页面刷新时应用到Link,不会随着当前路由的变化而动态应用
这与 react-redux 的连接功能有关,因为它抑制了上下文更新。要禁用抑制上下文更新,您可以在调用 connect()
方法时设置 pure: false
,如下所示:
//your component which has the custom NavLink as its child.
//(this component may be the any component from the list of
//parents and grandparents) eg., header
function mapStateToProps(state) {
return { someprops: state.someprops }
}
export default connect(mapStateToProps, null, null, {
pure: false
})(Header);
检查这里的问题:reactjs#470
在此处查看 pure: false
文档:docs
使用 react-router-dom@4.3.1
(尽管我猜任何 4.x.x
都应该),我们可以使用 withRouter
HOC 来完成此操作。例如,我想实现 Bootstrap 导航栏,因为它需要 <li class="nav-item">
而不是锚标记上的 class 或 active
,我制作了一个名为 NavItem
封装单个li.nav-item
。实现如下:
import React from "react";
import { Link, withRouter } from "react-router-dom";
const NavItem = ({ isActive, to, label }) => {
let classes = ["nav-item"];
if (isActive) classes.push("active");
return (
<li className={classes.join(" ")}>
<Link className="nav-link" to={to}>
{label}
</Link>
</li>
);
};
export default withRouter(({ location, ...props }) => {
const isActive = location.pathname === props.to;
console.log(location.pathname, props.to);
return <NavItem {...props} isActive={isActive} />;
});
如您所见,NavItem
只是一个无状态功能组件,它需要一个 isActive
属性来确定是否应添加 active
class。现在,要随着位置的变化更新这个道具,我们可以使用 withRouter
HOC。您可以将任何组件传递给此函数,它会在其道具中为它提供 { match, location, history }
个对象以及您传递的对象。在这里,我正在创建一个内联功能组件,它接收这些对象并使用 location.pathname
属性 确定当前 link 是否是活动的。这将为我们提供 Boolean
,我们可以 return 将 NavItem
和 isActive
设置为我们使用 location.pathname
.
可以找到一个这样的工作示例 here。如果有更简单的方法,请告诉我。
从 react-router-dom@4.3.1 开始,我们可以轻松地使用带有 activeClassName 的 NavLink 而不是 Link。示例:
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
class NavBar extends Component {
render() {
return (
<div className="navbar">
<ul>
<li><NavLink to='/1' activeClassName="active">1</NavLink></li>
<li><NavLink to='/2' activeClassName="active">2</NavLink></li>
<li><NavLink to='/3' activeClassName="active">3</NavLink></li>
</ul>
</div>
);
}
}
然后在您的 CSS 文件中:
.navbar li>.active {
font-weight: bold;
}
NavLink 将根据当前 URL.
将您的自定义样式属性添加到呈现的元素中文件是here
在活动导航元素上设置 class
import { NavLink } from 'react-router-dom';
&
<NavLink to="/Home" activeClassName="active">Home</NavLink>
这很容易做到,react-router-dom提供了所有。
import React from 'react';
import { matchPath, withRouter } from 'react-router';
class NavBar extends React.Component {
render(){
return(
<ul className="sidebar-menu">
<li className="header">MAIN NAVIGATION</li>
<li className={matchPath(this.props.location.pathname, { path: "/dashboard" }) ? 'active' : ''}><Link to="dashboard"><i className="fa fa-dashboard"></i>
<span>Dashboard</span></Link></li>
<li className={matchPath(this.props.location.pathname, { path: "/email_lists" }) ? 'active' : ''}><Link to="email_lists"><i className="fa fa-envelope-o"></i>
<span>Email Lists</span></Link></li>
<li className={matchPath(this.props.location.pathname, { path: "/billing" }) ? 'active' : ''}><Link to="billing"><i className="fa fa-credit-card"></i>
<span>Buy Verifications</span></Link></li>
</ul>
)
}
}
export default withRouter(NavBar);
使用 withRouter() HOC 包装您的导航组件将为您的组件提供一些道具: 1.匹配 2. 历史 3. 地点
这里我使用了 react-router 中的 matchPath() 方法来比较路径并决定 'li' 标签是否应该得到 "active" class 名字与否。我正在从 this.props.location.pathname.
访问该位置当我们的 link 被点击时,道具中的路径名称会发生变化,位置道具将得到更新 NavBar 也会得到 re-rendered 并且活动样式将得到应用
从路由器 v4 开始,我使用 'refs' 来设置父活动 class:
<ul>
<li>
<NavLink
innerRef={setParentAsActive}
activeClassName="is-active"
to={link}
>
{text}
</NavLink>
</ul>
NavLink
的 innerRef
属性接受回调函数,它将接收 DOM 节点作为参数。您可以使用任何可能的 DOM 操作,在这种情况下只需将父元素 (<li>
) 设置为具有相同的 class:
const setParentAsActive = node => {
if (node) {
node.parentNode.className = node.className;
}
};
缺点:
<a>
将有不必要的is-active
class(因为你只需要<li>
),或者你可以在回调中删除这个 class功能- 如果更改元素结构,f.e。将
a
标记包裹在span
中,您的回调将停止工作,但可以编写更复杂的 DOM 遍历函数 - 你必须做一些DOM操作
只需使用 NavLink
而不是 Link
。它会自动添加.active
class。
<Nav className="mr-auto">
<Nav.Link as={NavLink} to="/home">Home</Nav.Link>
<Nav.Link as={NavLink} to="/users">Users</Nav.Link>
</Nav>
扩展@BaiJiFeiLong的回答,在link中添加一个active={}
属性:
<Nav.Link as={Link} to="/user" active={pathname.startsWith('/user')}>User</Nav.Link>
当任何路径以“/user”开头时,这将显示 User
link 处于活动状态。为了在每次路径更改时更新,请在组件上包含 withRouter()
:
import React from 'react'
import { Link, withRouter } from 'react-router-dom'
import Navbar from 'react-bootstrap/Navbar'
import Nav from 'react-bootstrap/Nav'
function Header(props) {
const pathname = props.location.pathname
return (
<Navbar variant="dark" expand="sm" bg="black">
<Navbar.Brand as={Link} to="/">
Brand name
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link as={Link} to="/user" active={pathname.startsWith('/user')}>User</Nav.Link>
<Nav.Link as={Link} to="/about" active={pathname.startsWith('/about')}>About</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
)
}
export default withRouter(Header) // updates on every new page
使用 Jquery 进行活动 link:
$(function(){
$('#nav a').filter(function() {
return this.href==location.href
})
.parent().addClass('active').siblings().removeClass('active')
$('#nav a').click(function(){
$(this).parent().addClass('active').siblings().removeClass('active')
})
});
使用Jquery中指定的组件生命周期方法或文档就绪函数。
import React from 'react';
import {withRouter, Link} from "react-router-dom";
const SidenavItems = (props) => {
// create simple list of links
const items = [
{
type: "navItem",
icon: "home",
text: "Home",
link: "/",
restricted: false
},
{
type: "navItem",
icon: "user-circle",
text: "My Profile",
link: "/user",
restricted: false
},
{
type: "navItem",
icon: "sign-in",
text: "Login",
link: "/login",
restricted: false
},
];
const element = (item, i) => { // create elements (Links)
// check if this is a current link on browser
let active = "";
if (props.location.pathname === item.link) {
active = "active";
}
return (
<div key={i} className={item.type}>
<Link
to={item.link}
className={active} // className will be set to "active"
> // or ""
{item.text}
</Link>
</div>
)
};
const showItems = () => { // print elements
return items.map((item, i) => {
return element(item, i)
})
};
return (
<div>
{showItems()} // print all the links we created in list
</div>
)
};
export default withRouter(SidenavItems);
其中一种使用方式
当您使用功能组件时,请按照此处的说明进行操作。
- 在您的组件中添加一个变量
- 创建事件更改浏览器URLchange/or其他更改
- 重新分配当前路径(URL)
- 使用javascript匹配函数并设置为active或其他
这里使用上面的代码。
import React, { useEffect } from 'react';
import { Link } from 'react-router-dom';
const NavItems = () => {
let pathname = window.location.pathname;
useEffect(() => {
pathname = window.location.pathname;
}, [window.location.pathname]);
return (
<>
<li className="px-4">
<Link to="/home" className={`${pathname.match('/home') ? 'link-active' : ''}`}>Home</Link>
</li>
<li className="px-4">
<Link to="/about-me" className={`${pathname.match('/about-me') ? 'link-active' : ''}`}>About-me</Link>
</li>
<li className="px-4">
<Link to="/skill" className={`${pathname.match('/skill') ? 'link-active' : ''}`}>Skill</Link>
</li>
<li className="px-4">
<Link to="/protfolio" className={`${pathname.match('/protfolio') ? 'link-active' : ''}`}>Protfolio</Link>
</li>
<li className="pl-4">
<Link to="/contact" className={`${pathname.match('/contact') ? 'link-active' : ''}`}>Contact</Link>
</li>
</>
);
}
export default NavItems;
--- 谢谢 ---
当前 React Router 版本 5.2.0
activeStyle 是 NavLink 组件的 默认 css 属性 从 react-router-dom
这样我们就可以编写自己的自定义 css 以使其成为 active.In 这个例子我将背景设为透明并且文本设为 bold.And 我将其存储在名为 [=] 的常量中17=]有效
import React from "react";
import { NavLink} from "react-router-dom";
function nav() {
const isActive = {
fontWeight: "bold",
backgroundColor: "rgba(255, 255, 255, 0.1)",
};
return (
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<NavLink className="nav-link" to="/Shop" activeStyle={isActive}>
Shop
</NavLink>
</li>
</ul>
);
export default nav;
使用 React Hooks。
import React, { useState } from 'react';
export const Table = () => {
const [activeMenu, setActiveMenu] = useState('transaction');
return(
<>
<Link className="flex-1 mr-2">
<a
id="transaction"
className={
activeMenu == 'transaction'
? 'text-center block border border-blue-500 rounded py-2 px-4 bg-blue-500 hover:bg-blue-700 text-white'
: 'text-center block border border-white rounded hover:border-gray-200 text-blue-500 hover:bg-gray-200 py-2 px-4'
}
href="#"
onClick={() => {
setActiveMenu('transaction');
}}>
Recent Transactions
</a>
</Link>
<Link className="flex-1 mr-2">
<a
id="account"
className={
activeMenu == 'account'
? 'text-center block border border-blue-500 rounded py-2 px-4 bg-blue-500 hover:bg-blue-700 text-white'
: 'text-center block border border-white rounded hover:border-gray-200 text-blue-500 hover:bg-gray-200 py-2 px-4'
}
href="#"
onClick={() => {
setActiveMenu('account');
}}>
Account Statement
</a>
</LInk>
</>
)
}
对我来说有用的是使用 NavLink,因为它有这个活动 class 属性.
先导入
import { NavLink } from 'react-router-dom';
使用 activeClassName 获取活动 class 属性.
<NavLink to="/" activeClassName="active"> Home </NavLink> <NavLink to="/store" activeClassName="active"> Store </NavLink> <NavLink to="/about" activeClassName="active"> About Us </NavLink>
在 css 中设置您的 class 样式由 属性 激活。
.active{ color:#fcfcfc; }
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand>
<Nav.Link as="{NavLink}" to="/">Brand Name</Nav.Link>
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<nav className="me-auto">
<Nav.Link as="{NavLink}" to="/" exact>Home</Nav.Link>
<Nav.Link as="{NavLink}" to="/about">About</Nav.Link>
<Nav.Link as="{NavLink}" to="/contact">Contact</Nav.Link>
<NavDropdown title="Dropdown" id="basic-nav-dropdown">
<Nav.Link as="{NavLink}" to="/page1">Dropdown Link 1</Nav.Link>
<Nav.Link as="{NavLink}" to="/page2">Dropdown Link 2</Nav.Link>
<Nav.Link as="{NavLink}" to="/page3">Dropdown Link 3</Nav.Link>
</NavDropdown>
</nav>
</Navbar.Collapse>
</Container>
在 react-router-dom 文档中,您使用 navlink 而不是 link。 https://v5.reactrouter.com/web/api/NavLink
import { NavLink } from "react-router-dom";
<Nav>
<NavLink exact activeClassName="active--link" to="/" className="your class" > Home </NavLink>
<NavLink exact to="/classes" activeClassName="active--link" className="your class" > Classes </NavLink>
</Nav>
<NavLink to="/hello" activeClassName="active">Hello</NavLink>
React Router v6:
来源:Active NavLink 类 与 React Router
您需要使用 className
属性,它现在接受一个函数并传递一个 isActive
布尔值 属性:
<NavLink
to="users"
className={({ isActive }) => (isActive ? 'active' : 'inactive')}
>
Users
</NavLink>
这也非常适合添加多个 类,并且是 v6 beta 中的重大更改:
<NavLink
to="users"
className={({ isActive }) =>
isActive ? 'bg-green-500 font-bold' : 'bg-red-500 font-thin'
}
>
Users
</NavLink>
阅读更多内容并进行现场演示:Active NavLink 类 with React Router
<NavLink to='/' activeClassName='active'>
Home
</NavLink>
我只是使用了 NavLink
和 activeClassName
而没有将其包装在任何组件或其他东西中,但我的代码仍然有效:)
在 React 路由器版本 6 中,我们通过 NavLink 完成它并设置它的类名 属性。
我们在这里指定了一个函数,每次路由更改时都会调用该函数。
import { NavLink } from 'react-router-dom';
import classes from './MainHeader.module.css';
const MainHeader = () => {
return (
<header className={classes.header}>
<nav>
<ul>
<li>
<NavLink className={({isActive}) => isActive ? classes.active : ''} to='/welcome'>
Welcome
</NavLink>
</li>
<li>
<NavLink className={({isActive}) => isActive ? classes.active : ''} to='/products'>
Products
</NavLink>
</li>
</ul>
</nav>
</header>
);
};
export default MainHeader;
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
class NavBar extends Component {
render() {
return (
<div className="navbar">
<ul>
<li><NavLink to='/1' activeClassName="active">1</NavLink></li>
<li><NavLink to='/2' activeClassName="active">2</NavLink></li>
<li><NavLink to='/3' activeClassName="active">3</NavLink></li>
</ul>
</div>
);
}
}
这适用于我的...