How to set activeClassName for wrapper element of

2019-01-13 03:17发布

I am new to the ReactJS world, and would like to know how can I pass active class name to the <li> element instead of <a>(Link) element.

Now I have this kind of code. The anchor class changes when clicked.

<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>

But I would like to get something similar to:

<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>

Thanks in advance

10条回答
趁早两清
2楼-- · 2019-01-13 03:40

I'm using React Router v4.2 and I couldn't get the reference to the router object from the wrapping component, because the context is not available.

This did not work:

const { router } = this.context

I like @mpen's answer, but I'm using nested routes and I don't want to change the file where I have the routing component defined.

What I did is compared the location.pathname with to :

const NavItem = withRouter((props) => {
const { to, children, location } = props;
return (
    <li className={location.pathname == to ? 'active' : null}>
        <Link to={to}>{children}</Link >
    </li>
)});
查看更多
我只想做你的唯一
3楼-- · 2019-01-13 03:42

Using React Router v4, I only got it to work by including the <li> tags within the NavLink component. The solutions which have the <li> tags wrapping the links resulted in the HOME <li> tag always having the active class.

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

class Header extends React.Component {

  render() {
    return (
      <div>
        <header>

          <nav>
            <ul>
              <NavLink activeClassName={"active"} exact={true} to="/"><li>Home</li></NavLink>
              <NavLink activeClassName={"active"} to="/about"><li>About</li></NavLink>
              <NavLink activeClassName={"active"} to="/courses"><li>Courses</li></NavLink>
            </ul>
          </nav>

        </header>
      </div>
    )
  }
}

export default Header

I adjusted the li and a CSS selectors accordingly.

查看更多
别忘想泡老子
4楼-- · 2019-01-13 03:43

You need to enclose your <li> as a router aware component:

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>
    )
  }
}

Usage:

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

I took inspration from the react-router-bootstrap module, https://github.com/react-bootstrap/react-router-bootstrap/blob/master/src/LinkContainer.js. I didn't test it though so let me know how it goes.

查看更多
来,给爷笑一个
5楼-- · 2019-01-13 03:44

In stead of using <Link />, I use <NavLink /> and It works as well.

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>
        );
    }
}
查看更多
The star\"
6楼-- · 2019-01-13 03:48
/**
 * 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

Usage:

<ul className="nav nav-tabs"> 
  <NavItem to='/home' index={true} >Home</NavItem>
  <NavItem to='/about'>About</NavItem>
</ul>
查看更多
小情绪 Triste *
7楼-- · 2019-01-13 03:50

The other answers don't seem to work in React Router v4. Here's how you can do it:

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,
};
查看更多
登录 后发表回答