React Router v4 setting activeClass on parent

这一生的挚爱 提交于 2019-12-01 15:42:22

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.

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

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!