Реактивный маршрутизатор: как отключить <link> , если он активен?

Как отключить <Link> в реакторе, если его URL уже активен? Например, если мой URL-адрес не будет меняться при щелчке по <Link> я хочу предотвратить щелчок на всех или сделать <span> вместо <Link>.

Единственным решением, которое приходит мне на ум, является использование activeClassName (или activeStyle) и установка pointer-events: none; , но я бы предпочел использовать решение, которое работает в IE9 и IE10.

Ответы

Ответ 1

Я не буду спрашивать, почему вы хотите этого поведения, но я думаю, вы можете обернуть <Link/> в свой собственный компонент ссылок.

<MyLink to="/foo/bar" linktext="Maybe a link maybe a span" route={this.props.route}/>

class MyLink extends Component {
    render () {
        if(this.props.route === this.props.to){
            return <span>{this.props.linktext}</span>
        }
        return <Link to={this.props.to}>{this.props.linktext}</Link>
    }
}

(ES6, но вы, вероятно, получите общую идею...)

Ответ 2

Вы можете использовать атрибут CSS pointer-events. Это будет работать с большим количеством браузеров. Например, вы код:

class Foo extends React.Component {
  render() {
    return (
      <Link to='/bar' className='disabled-link'>Bar</Link>
    );
  }
}

и CSS:

.disabled-link {
  pointer-events: none;
}

Ссылки:

В ответе Как отключить HTML-ссылки предложено использовать disabled и pointer-events: none для максимальной поддержки браузера.

a[disabled] {
    pointer-events: none;
}

Ссылка на источник: Как отключить ссылку

Ответ 3

Другая возможность - отключить событие клика, если он уже на том же пути. Вот решение, которое работает с response-router v4.

import React, { Component } from 'react';
import { Link, withRouter } from 'react-router-dom';

class SafeLink extends Component {
    onClick(event){
        if(this.props.to === this.props.history.location.pathname){
            event.preventDefault();
        }

        // Ensure that if we passed another onClick method as props, it will be called too
        if(this.props.onClick){
            this.props.onClick();
        }
    }

    render() {
        const { children, onClick, ...other } = this.props;
        return <Link onClick={this.onClick.bind(this)} {...other}>{children}</Link>
    }
}

export default withRouter(SafeLink);

Затем вы можете использовать свою ссылку, поскольку (любые дополнительные реквизиты от Link будут работать):

<SafeLink className="some_class" to="/some_route">Link text</SafeLink>

Ответ 4

Это работает для меня:

<Link to={isActive ? '/link-to-route' : '#'} />

Ответ 5

Все доброжелательность React Router NavLink с отключенной способностью.

import React from "react"; // v16.3.2
import { withRouter, NavLink } from "react-router-dom"; // v4.2.2

export const Link = withRouter(function Link(props) {
  const { children, history, to, staticContext, ...rest } = props;
  return <>
    {history.location.pathname === to ?
      <span>{children}</span>
      :
      <NavLink {...{to, ...rest}}>{children}</NavLink>
    }
  </>
});

Ответ 6

Компонент React Router Route имеет три различных способа визуализации контента на основе текущего маршрута. В то время как component чаще всего используется для показа компонента только во время сопоставления, компонент children принимает обратный вызов ({match}) => {return <stuff/>}, который может отображать вещи, сопоставленные при сопоставлении , даже когда маршруты не совпадают.

Я создал класс NavLink, который заменяет ссылку на span и добавляет класс, когда активен его маршрут to.

class NavLink extends Component {
  render() {
    var { className, activeClassName, to, exact, ...rest } = this.props;
    return(
      <Route
        path={to}
        exact={exact}
        children={({ match }) => {
          if (match) {
            return <span className={className + " " + activeClassName}>{this.props.children}</span>;
          } else {
            return <Link className={className} to={to} {...rest}/>;
          }
        }}
      />
    );
  }
}

Затем создайте навигационную ссылку примерно так

<NavLink to="/dashboard" className="navlink" activeClassName="active">

React Router NavLink делает что-то похожее, но это все же позволяет пользователю переходить по ссылке и загружать историю.

Ответ 7

С помощью React Router V4 вы можете легко передать отключенную опору и дать ей условие

  <Link disabled={!record} to="/employees">Go Somewhere</Link>

Ответ 8

На основе ответа и компонента nbeuchat - я создал собственную улучшенную версию компонента, которая переопределяет компонент react router Link для моего проекта.

В моем случае мне пришлось разрешить передачу объекта в to prop (как это делает нативная ссылка react-router-dom), также я добавил проверку search query и hash вместе с pathname

import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Link as ReactLink } from 'react-router-dom';
import { withRouter } from "react-router";

const propTypes = {
  to: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.object]),
  location: PropTypes.object,
  children: PropTypes.node,
  onClick: PropTypes.func,
  disabled: PropTypes.bool,
  staticContext: PropTypes.object
};

class Link extends Component {
  handleClick = (event) => {
    if (this.props.disabled) {
      event.preventDefault();
    }

    if (typeof this.props.to === 'object') {
      let {
        pathname,
        search = '',
        hash = ''
      } = this.props.to;
      let { location } = this.props;

      // Prepend with ? to match props.location.search
      if (search[0] !== '?') {
        search = '?' + search;
      }

      if (
        pathname === location.pathname
        && search === location.search
        && hash === location.hash
      ) {
        event.preventDefault();
      }
    } else {
      let { to, location } = this.props;

      if (to === location.pathname + location.search + location.hash) {
        event.preventDefault();
      }
    }

    // Ensure that if we passed another onClick method as props, it will be called too
    if (this.props.onClick) {
      this.props.onClick(event);
    }
  };

  render() {
    let { onClick, children, staticContext, ...restProps } = this.props;
    return (
      <ReactLink
        onClick={ this.handleClick }
        { ...restProps }
      >
        { children }
      </ReactLink>
    );
  }
}

Link.propTypes = propTypes;

export default withRouter(Link);

Ответ 9

Я думаю, вы должны атаковать = null, чтобы отключить ссылку.

См. Пример здесь fooobar.com/info/5893208/...