React Router v4 setting activeClass on parent

前端 未结 4 1048
猫巷女王i
猫巷女王i 2021-01-17 16:13

Not too familiar with react router, but I need the functionality of the NavLink to set the active class on the parent li element, and not the a ele

相关标签:
4条回答
  • 2021-01-17 16:35

    Check this one

    class LiNavLink extends React.Component<NavLinkProps> {
        render() {
            return (
                <Route exact={this.props.exact} path={this.props.to.toString()}>
                    {
                        ({ match }) =>
                            <li className={match ? 'active' : undefined}>
                                <Link to={this.props.to} >
                                   {this.props.children}
                                </Link>
                            </li>
                    }
                </Route>
            );
        }
    }
    
    0 讨论(0)
  • 2021-01-17 16:37

    I found that by using CSS you can make the active link expand to fill up it's parent <li> element by setting display:block; in the active class.

    For example if our link was:

    <li>
      <NavLink to="/overview" className=styles.sideLink activeClassName=styles.sideLinkSelected>
        Overview 
      </NavLink>
    </li>
    

    then our CSS would be:

    &__sideLinkSelected
    {
      background-color: blue;
      display:block;
    }
    
    0 讨论(0)
  • 2021-01-17 16:52

    I am just starting with the react, so not sure if this is the best practices, but after going through router v4 docs, I used withRouter props -> location.pathname and compared it to my route.

    Here is the Navigation.js:

    import React from 'react';
    import { withRouter } from 'react-router-dom';
    import NavLink from '../General/NavLink';
    
    const activeClass = (path, link) => {
        if (path === link) {
            return true;
        }
        return false;
    };
    
    const Navigation = props => {
        const { location } = props;
        return (
            <ul className="menu menu--main nano-content">
                <NavLink
                    to="/"
                    parentClass={
                        activeClass(location.pathname, '/')
                            ? 'menu__item menu__item--active'
                            : 'menu__item'
                    }
                    linkClass="menu__link effect effect--waves"
                >
                    Dashboard
                </NavLink>
                <NavLink
                    to="/users"
                    parentClass={
                        activeClass(location.pathname, '/users')
                            ? 'menu__item menu__item--active'
                            : 'menu__item'
                    }
                    linkClass="menu__link effect effect--waves"
                >
                    Users
                </NavLink>
                <NavLink
                    to="/projects"
                    parentClass={
                        activeClass(location.pathname, '/projects')
                            ? 'menu__item menu__item--active'
                            : 'menu__item'
                    }
                    linkClass="menu__link effect effect--waves"
                >
                    Projects
                </NavLink>
                <NavLink
                    href="http://google.com"
                    parentClass="menu__item"
                    linkClass="menu__link effect effect--waves"
                >
                    Google
                </NavLink>
            </ul>
        );
    };
    
    export default withRouter(Navigation);
    

    From there you have parent and child classes that you can use on child component.

    0 讨论(0)
  • 2021-01-17 16:53

    In v4 after lots of tries I did.

    Here my working code.

    import React, { Component } from "react";
    import logo from "../../logo.svg";
    import { Link, withRouter } from "react-router-dom";
    import PropTypes from "prop-types";
    
    class Navbar extends Component {
      static propTypes = {
        match: PropTypes.object.isRequired,
        location: PropTypes.object.isRequired,
        history: PropTypes.object.isRequired
      };
    
      state = {};
    
      getNavLinkClass = path => {
        return this.props.location.pathname === path
          ? "nav-item active"
          : "nav-item";
      };
      render() {
        return (
          <nav className="navbar navbar-expand-lg navbar-dark bg-dark">
            <Link className="navbar-brand" to="/">
              <img
                src={logo}
                width="30"
                height="30"
                className="d-inline-block align-top"
                alt=""
              />
              Utility
            </Link>
            <button
              className="navbar-toggler"
              type="button"
              data-toggle="collapse"
              data-target="#navbarNav"
              aria-controls="navbarNav"
              aria-expanded="false"
              aria-label="Toggle navigation"
            >
              <span className="navbar-toggler-icon" />
            </button>
            <div className="collapse navbar-collapse" id="navbarNav">
              <ul className="navbar-nav">
                <li className={this.getNavLinkClass("/")}>
                  <Link className="nav-link" to="/">
                    Home
                  </Link>
                </li>
                <li className={this.getNavLinkClass("/age-counter")}>
                  <Link className="nav-link" to="/age-counter">
                    Age Counter
                  </Link>
                </li>
              </ul>
            </div>
          </nav>
        );
      }
    }
    
    export default withRouter(Navbar);
    

    Demo working Code Sandbox

    0 讨论(0)
提交回复
热议问题