如何在 react-router 中为 Link 或 IndexLink 的包装元素设置 activeClassName?

IT技术 javascript reactjs react-router redux
2021-04-19 16:41:19

我是 ReactJS 世界的新手,想知道如何将活动类名传递给<li>元素而不是<a>(Link)元素。

现在我有这种代码。单击时锚点类会发生变化。

<li><IndexLink to='/' activeclassName='active'>A</IndexLink></li>
<li><Link to='/b' activeclassName='active'>B</Link></li>
<li><Link to='/c' activeclassName='active'>C</Link></li>

但我想得到类似的东西:

<li activeclassName='active'><IndexLink to='/'>A</IndexLink></li>
<li activeclassName='active'><Link to='/b'>B</Link></li>
<li activeclassName='active'><Link to='/c'>C</Link></li>

提前致谢

6个回答

您需要将您的<li>作为路由器感知组件附上

import { Link, IndexLink } from 'react-router'

class NavItem extends React.Component {
  render () {
    const { router } = this.context
    const { index, onlyActiveOnIndex, to, children, ...props } = this.props

    const isActive = router.isActive(to, onlyActiveOnIndex)
    const LinkComponent = index ? Link : IndexLink

    return (
      <li className={isActive ? 'active' : ''}>
        <LinkComponent {...props}>{children}</LinkComponent>
      </li>
    )
  }
}

用法:

<ul>
  <NavItem to='/' index={true}>Home</NavItem>
  <NavItem to='/a'>A</NavItem>
</ul>

我从 react-router-bootstrap modulehttps://github.com/react-bootstrap/react-router-bootstrap/blob/master/src/LinkContainer.js获取灵感我没有测试它,所以让我知道它是怎么回事。

您可能需要确保您的组件获得上下文,例如 router: PropTypes.object.isRequired
2021-05-25 16:41:19
不是router通过上下文,而是使用包中withRouterHOCreact-router通过 props 获取路由器。这也将在页面更改时更新链接的活动状态,否则 React 无法知道是否isActive已更改。
2021-06-16 16:41:19
根据您的设置,您可能需要 NavLi.contextTypes = { router: React.PropTypes.object }; export default NavLi;
2021-06-20 16:41:19
withRouter(...)对我不起作用。this.context.router仍然未定义:(
2021-06-20 16:41:19

其他答案似乎在 React Router v4 中不起作用。您可以这样做:

import React, {PropTypes} from 'react'
import {Route, Link} from 'react-router-dom'
import styles from './styles.less';

export default function NavItem({children, to, exact}) {
    return (
        <Route path={to} exact={exact} children={({match}) => (
            <li className={match ? styles.activeRoute : null}>
                <Link to={to}>{children}</Link>
            </li>
        )}/>
    )
}

NavItem.propTypes = {
    to: PropTypes.string.isRequired,
    exact: PropTypes.bool,
    children: PropTypes.node.isRequired,
};
@mpen 我知道你的意思,尽管在这种情况下 a0会产生相同的效果,不是吗?
2021-05-28 16:41:19
@Sag1v 我不再喜欢使用那种语法了。当它评估为时我得到了一点0,我的用户界面中有一个流浪的 0。如果您不小心,可能会产生更严重的错误。
2021-05-29 16:41:19
我不会使用三元运算符,而是使用<li className={match && styles.activeRoute}>更简洁的。
2021-06-09 16:41:19
这次真是万分感谢。我会添加...props到 params 并将其<Link to={to} {...props}>{children}</Link>用于更灵活。
2021-06-13 16:41:19
更新了 jsfiddle 上面@mpen 给出的答案:jsfiddle.net/69z2wepo/99537
2021-06-15 16:41:19
/**
 * A navigation component
 */
import React, { Component } from 'react'
import { Link, IndexLink, withRouter } from 'react-router'

import styles from './styles.scss'

class NavItem extends Component {
  render () {
    const { router } = this.props
    const { index, to, children, ...props } = this.props

    let isActive
    if( router.isActive('/',true) && index ) isActive = true
    else  isActive = router.isActive(to)
    const LinkComponent = index ?  IndexLink : Link

    return (
      <li className={isActive ? 'active' : ''}>
        <LinkComponent to={to} {...props}>{children}</LinkComponent>
      </li>
    )
  }
}

NavItem = withRouter(NavItem)

export default NavItem

用法:

<ul className="nav nav-tabs"> 
  <NavItem to='/home' index={true} >Home</NavItem>
  <NavItem to='/about'>About</NavItem>
</ul>
没有用:router对我来说是未定义的,在this.props:-(
2021-05-31 16:41:19
虽然乍一看它与 Marc 的答案相似,但这个答案对我来说效果更好。withRouter似乎是当前版本中访问路由器的方式。
2021-06-12 16:41:19
这对我有用,但因为我使用的是 IndexLink,所以我做了一个改变: else isActive = router.isActive(to, true) 。我必须向 IsActive 函数添加 true,否则 isActive 总是为“/”返回 true。
2021-06-14 16:41:19
{/* Make sure that `location` is injected into this component */}
<ul className="nav navbar-nav">
  <li className={location.pathname === '/' && 'active'}>
    <Link to='/'>
      Home page
    </Link>
  </li>
  <li className={location.pathname.startsWith('/about') && 'active'}>
    <Link to='/about'>
      About us
    </Link>
  </li>
</ul>
最简单的答案。
2021-05-28 16:41:19

<Link />没有使用,而是使用<NavLink />和 它也能工作。

import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';

//.....

export default class AppNav extends Component {

    render (){
        return (
                <header>
                    <ul className="main-nav">
                        <li><NavLink activeClassName={"active"} exact={true} to="/">Home</NavLink></li>
                        <li><NavLink activeClassName={"active"} to="/about">About</NavLink></li>
                        <li><NavLink activeClassName={"active"} to="/courses">Courses</NavLink></li>
                    </ul>
                </header>
        );
    }
}
这不是问题。他问了父类。
2021-05-23 16:41:19
为我工作,不需要任何解决方法,应该将其标记为最佳答案。
2021-05-25 16:41:19
这解决了我的问题。我想知道它们之间有什么区别使它起作用?
2021-05-31 16:41:19
OP 想要将类添加到 Link 的父元素,而不是 Link 本身。
2021-06-01 16:41:19
它是否设置了父<li>元素的类对我来说,它只是设置<a><NavLink>.
2021-06-03 16:41:19