How to set activeClassName for wrapper element of Link or IndexLink in react-router?

abekenza picture abekenza · Jan 28, 2016 · Viewed 33.6k times · Source

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

Answer

Marc Greenstock picture Marc Greenstock · Jan 29, 2016

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.