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条回答
Bombasti
2楼-- · 2019-01-13 03:51

Great answer.

Just change the following to get it working...

LinkComponent = index ? IndexLink : Link //If its true you want an IndexLink 

//Also link needs to be...
<NavItem to="/" onlyActiveOnIndex index={true}>Home</NavItem>
查看更多
beautiful°
3楼-- · 2019-01-13 03:54

Using react 15.1.0, react-router 2.5.0 and bootstrap 3.3 (this is less important), I developed this solution for making the links active:

npm install --save classnames

npm install --save lodash

The component:

import React from 'react';
import { Link, IndexLink } from 'react-router';
import _ from 'lodash';
import classnames from 'classnames';

class NavItem extends React.Component {
  constructor(props) {
    super(props);

    // The default state
    this.state = {
      isActive: false,
      unregisterRouteListener: false
    };

    // Binding for functions
    this.locationHasChanged = this.locationHasChanged.bind(this);
  }

  componentDidMount() {
    // Check if component is active on mount and add listener on route change
    this.setState({
      isActive: this.context.router.isActive(this.props.to, true),
      unregisterRouteListener: this.context.router.listen(this.locationHasChanged)
    });
  }

  componentWillUnmount() {
    if (this.state.unregisterRouteListener) {
      // Remove the listener
      this.state.unregisterRouteListener();
    }

    // Reset the state
    this.setState({
      isActive: false,
      unregisterRouteListener: false
    });
  }

  // Update the state of the component, based on the router path
  locationHasChanged() {
    this.setState({
      isActive: this.context.router.isActive(this.props.to, true)
    });
  }

  render () {
    let { index } = this.props;
    let LinkComponent = index ? Link : IndexLink;
    let newProps = _.omit(this.props, 'router');

    return (
      <li className={classnames('', this.state.isActive ? 'active' : '' )}>
        <LinkComponent {...newProps}>
          {this.props.children}
        </LinkComponent>
      </li>
    );
  }
}

NavItem.contextTypes = {
  router: React.PropTypes.object
};

export default NavItem;

Usage:

<NavItem to="/list">List</NavItem>

I am a beginner with React, so the above solution surely needs improvements and might contain approach errors. However, it might also contain useful information or a starting point to those interested.

Any feedback or suggestions are more than welcome. Thanks! :)

查看更多
小情绪 Triste *
4楼-- · 2019-01-13 04:00

Try with react-router-active-component.

I couldn't get any of the previous answers to easily work due to incompatibilities between react or typescript versions (this is definitely not a mature ecosystem), but this component did the trick, and can be applied to other elements than li if needed:

import activeComponent from 'react-router-active-component'
let NavItem = activeComponent('li');
...
<NavItem to='/' onlyActiveOnIndex>Home</NavItem>
<NavItem to='/generate-keywords'>Generate keywords</NavItem>
查看更多
疯言疯语
5楼-- · 2019-01-13 04:02
{/* 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>
查看更多
登录 后发表回答