11

不太熟悉反应路由器,但我需要 NavLink 的功能来在父li元素上设置活动类,而不是a元素。

为了实现这一点,我只是查看了源代码NavLink并将其复制到一个新元素中。(使用 typescript 的示例,但与 js 几乎相同)

import * as React from 'react';
import { Link, withRouter, Route } from 'react-router-dom';


class LiNavLink extends React.Component<any, {}> {
    render() {
        const {to,exact, strict, activeClassName, className, activeStyle, style, isActive: getIsActive, ...rest } = this.props;
        return (
            <Route
                path={typeof to === 'object' ? to.pathname : to}
                exact={exact}
                strict={strict}
                children={({ location, match }) => {
                    const isActive = !!(getIsActive ? getIsActive(match, location) : match)

                    return (
                        <li 
                            className={isActive ? [activeClassName, className].join(' ') : className}
                            style={isActive ? { ...style, ...activeStyle } : style}>
                            <Link
                                to={to}
                                {...rest}
                            />
                        </li>
                    )
                }}
            />
        );
    }
}

export default LiNavLink;

然后是用法:

<ul>
   <LiNavLink activeClassName='active' exact={true} strict to="/example"><span>Active</span></LiNavLink>
   <LiNavLink activeClassName='active' exact={true} strict to="/example/archived"><span>Archived</span></LiNavLink>
</ul>

我正在使用一个HashRouter并且由于某种我无法弄清楚的原因,当路线改变时它不会更新,只有当我硬“刷新”页面时它才会更新它应该如何更新。

我相信它永远不会更新,因为道具永远不会改变?所以它不知道更新自己?

我怎样才能得到这个更新?还是我的问题在其他地方?

4

4 回答 4

3

在我做了很多尝试之后,在 v4 中。

这是我的工作代码。

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

演示工作代码沙箱

工作 gif 图像

于 2019-02-07T12:33:41.883 回答
1

检查这个

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>
        );
    }
}
于 2020-01-27T14:47:59.793 回答
0

我只是从反应开始,所以不确定这是否是最佳实践,但是在浏览了路由器 v4 文档之后,我使用了 withRouter props -> location.pathname 并将其与我的路由进行了比较。

这是 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);

从那里您可以在子组件上使用父类和子类。

于 2018-09-01T14:26:31.367 回答
-2

我发现通过使用 CSS,您可以通过在活动类中<li>进行设置来扩展活动链接以填充其父元素。display:block;

例如,如果我们的链接是:

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

那么我们的 CSS 将是:

&__sideLinkSelected
{
  background-color: blue;
  display:block;
}
于 2017-08-16T08:20:28.663 回答