我使用Link
创建了一个自举式边栏。以下是我的代码片段:
<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>
I want to set the class for the active path to `active` on the wrapping element `<li>`. I see there are other solutions out there that show how to do this *kindof* (https://stackoverflow.com/questions/34410051/conditionally-set-active-class-on-menu-using-react-router-current-route), however I don't think that is the best way to set an active class on a wrapper to a `Link`.
I also found https://github.com/insin/react-router-active-component but it feels like it is unnecessary.
In React Router, is this possible or do I need to use an external solution?
答案 0 :(得分:72)
在链接组件上,您现在可以添加 activeClassName 或设置 activeStyle 。
这些允许您轻松地将样式添加到当前活动的链接。
以前,您可以创建一个自定义组件,其工作方式类似于使用以下逻辑链接的包装器。
在名为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>
答案 1 :(得分:24)
React-Router V4 附带开箱即用的NavLink组件
要使用,只需将activeClassName
属性设置为您已适当设置样式的类,或直接将activeStyle
设置为您想要的样式。有关详细信息,请参阅the docs。
<NavLink
to="/hello"
activeClassName="active"
>Hello</NavLink>
答案 2 :(得分:12)
使用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;
然后如上所述使用它。
答案 3 :(得分:6)
我不喜欢创建自定义组件的想法,因为如果你有一个不同的包装元素,你将不得不创建另一个自定义组件等。此外,它只是矫枉过正。所以我只是使用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并对其进行样式化。
答案 4 :(得分:5)
对我来说,有效的方法是使用NavLink,因为它具有此活动的类属性。
首先导入
import { NavLink } from 'react-router-dom';
使用activeClassName获取活动类属性。
<NavLink to="/" activeClassName="active">
Home
</NavLink>
<NavLink to="/store" activeClassName="active">
Store
</NavLink>
<NavLink to="/about" activeClassName="active">
About Us
</NavLink>
通过active属性在CSS中设置类的样式。
.active{
color:#fcfcfc;
}
答案 5 :(得分:5)
这是我的方式,使用道具的位置。 我不知道但是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 class="nav navbar-nav navbar-right">
<li class={homeClass}><Link to="/">Home</Link></li>
<li class={aboutClass}><Link to="about" activeClassName="active">About</Link></li>
<li class={contactClass}><Link to="contact" activeClassName="active">Contact</Link></li>
</ul>
</div>
);}}
答案 6 :(得分:3)
你实际上可以复制here里面的内容
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源代码并删除不需要的部分;)
答案 7 :(得分:2)
使用react-router-dom@4.3.1
(尽管我猜测任何4.x.x
),我们可以使用withRouter
HOC来完成此任务。例如,我想实现Bootstrap导航栏,因为它需要active
上的<li class="nav-item">
类,而不是锚标记,我创建了一个名为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
类。现在,要在位置发生变化时更新此道具,我们可以使用withRouter
HOC。您可以将任何组件传递给此函数,并且它会在其道具中提供{ match, location, history }
个对象以及您传递的对象。在这里,我正在创建一个内联的功能组件,它接收这些对象并使用location.pathname
属性确定当前链接是否是活动链接。这将给我们Boolean
,我们可以将NavItem
和isActive
设置为我们使用location.pathname
计算的值。
可以找到here的工作示例。如果有更简单的方法,请告诉我。
答案 8 :(得分:2)
只需使用round (((`tbl_products`.`cost` * (`tbl_tax`.`amount` / 100)) + `tbl_products`.`cost`),n)
而不是NavLink
。它将自动添加Link
类。
.active
答案 9 :(得分:2)
当前反应路由器版本5.2.0
activeStyle 是NavLink组件的默认CSS属性,该属性是从 react-router-dom
导入的因此我们可以编写自己的自定义CSS使其处于活动状态。在此示例中,我使背景透明且文本变为粗体,并将其存储在名为 isActive
的常量中 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;
答案 10 :(得分:1)
从react-router-dom@4.3.1开始,我们可以轻松地使用带有activeClassName而不是Link的NavLink。例如:
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
答案 11 :(得分:1)
要在活动导航元素上设置类
import { NavLink } from 'react-router-dom';
&
<NavLink to="/Home" activeClassName="active">Home</NavLink>
答案 12 :(得分:1)
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);
答案 13 :(得分:1)
使用功能组件时,请按照此处的说明进行操作。
在此处使用上面的代码。
window.addEventListener("load", function(){
alert("hi")
});
---谢谢---
答案 14 :(得分:0)
当您使用 react-redux 进行状态管理并且某些父组件'connected'时,Vijey的答案有点问题redux商店。 activeClassName 仅在刷新页面时应用于链接,并且在当前路由更改时不会动态应用。
这与 react-redux 的connect函数有关,因为它抑制了上下文更新。要禁用对上下文更新的抑制,您可以在调用pure: false
方法时设置connect()
,如下所示:
//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
答案 15 :(得分:0)
做到这一点非常容易,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'标签是否应该获得“活动的”类名。和我从this.props.location.pathname访问位置。
点击我们的链接时,将在道具中更改路径名称,位置道具将被更新NavBar也将被重新渲染并采用活动样式
答案 16 :(得分:0)
自路由器v4起,我使用'refs'来设置父活动类:
<ul>
<li>
<NavLink
innerRef={setParentAsActive}
activeClassName="is-active"
to={link}
>
{text}
</NavLink>
</ul>
NavLink
的{{1}}道具接受回调函数,该函数将接收DOM节点作为参数。您可以使用任何可能的DOM操作,在这种情况下,只需将父元素(innerRef
)设置为具有相同的类:
<li>
缺点:
const setParentAsActive = node => {
if (node) {
node.parentNode.className = node.className;
}
};
将具有不必要的<a>
类(因为您仅需要is-active
使用它),或者您可以在回调函数中删除该类。<li>
标签包裹在a
内,您的回调将停止工作,但是可以编写更复杂的DOM遍历函数答案 17 :(得分:0)
扩展@BaiJiFeiLong的答案,在链接中添加active={}
属性:
<Nav.Link as={Link} to="/user" active={pathname.startsWith('/user')}>User</Nav.Link>
当任何路径以'/ user'开头时,这将显示User
链接处于活动状态。为了随着路径的变化而更新,请在组件上添加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
答案 18 :(得分:0)
使用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>
</>
)
}
答案 19 :(得分:-3)
使用Jquery激活链接:
$(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中指定的组件生命周期方法或文档准备功能。