Javascript react-router:如何禁用 <Link>,如果它处于活动状态?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35963070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:26:15  来源:igfitidea点击:

react-router: How to disable a <Link>, if its active?

javascriptreactjsreact-router

提问by Pipo

How can I disable a <Link>in react-router, if its URL already active? E.g. if my URL wouldn't change on a click on <Link>I want to prevent clicking at all or render a <span>instead of a <Link>.

<Link>如果其 URL 已处于活动状态,如何禁用react-router 中的一个?例如,如果我的 URL 在点击时不会改变,<Link>我想完全阻止点击或呈现一个<span>而不是<Link>.

The only solution which comes to my mind is using activeClassName(or activeStyle) and setting pointer-events: none;, but I'd rather like to use a solution which works in IE9 and IE10.

我想到的唯一解决方案是使用activeClassName(or activeStyle) 和 setting pointer-events: none;,但我更愿意使用适用于 IE9 和 IE10 的解决方案。

采纳答案by dannyjolie

I'm not going to ask why you would want this behavior, but I guess you can wrap <Link />in your own custom link component.

我不会问你为什么想要这种行为,但我想你可以包装<Link />在你自己的自定义链接组件中。

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

<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, but you probably get the general idea...)

(ES6,但您可能已经大致了解了...)

回答by Denis Bubnov

You can use CSS's pointer-eventsattribute. It will be works with more browsers. For example your JS code:

您可以使用 CSS 的pointer-events属性。它将适用于更多浏览器。例如你的JS代码:

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

and CSS:

和 CSS:

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

Links:

链接:

The How to disable HTML linksanswer attached suggested using both disabledand pointer-events: nonefor maximum browser-support.

所附的如何禁用 HTML 链接答案建议同时使用disabledpointer-events: none以获得最大的浏览器支持。

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

Link to source: How to disable Link

链接到源:如何禁用链接

回答by nbeuchat

Another possibility is to disable the click event if clicking already on the same path. Here is a solution that works with react-router v4.

另一种可能性是如果已经在同一路径上单击,则禁用单击事件。这是一个适用于 react-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);

You can then use your link as (any extra props from Linkwould work):

然后你可以使用你的链接(任何额外的道具Link都可以):

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

回答by tretapey

This works for me:

这对我有用:

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

回答by fsenart

Allthe goodness of React Router NavLinkwith the disableability.

具有禁用功能的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>
    }
  </>
});

回答by Wesss

React Router's Routecomponent has three different waysto render content based on the current route. While componentis most typically used to show a component only during a match, the childrencomponent takes in a ({match}) => {return <stuff/>}callback that can render things cased on match even when the routes don't match.

React Router 的Route组件有三种不同的方式来根据当前路由渲染内容。虽然component最常用于仅在匹配期间显示组件,但该children组件接受一个({match}) => {return <stuff/>}回调,即使路由不匹配,该回调也可以渲染大小写匹配的内容

I've created a NavLink class that replaces a Link with a span and adds a class when its toroute is active.

我创建了一个 NavLink 类,它用一个跨度替换了一个链接,并在其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}/>;
          }
        }}
      />
    );
  }
}

Then create a navlink like so

然后像这样创建一个导航链接

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

React Router's NavLinkdoes something similar, but that still allows the user to click into the link and push history.

React Router 的 NavLink做了类似的事情,但它仍然允许用户点击链接并推送历史记录。

回答by Benji

Based on nbeuchat's answer and component - I've created an own improved version of component that overrides react router'sLinkcomponent for my project.

基于 nbeuchat 的答案和组件 - 我创建了一个自己的改进版本的组件,它覆盖react router'sLink了我的项目的组件。

In my case I had to allow passing an object to toprop (as native react-router-domlink does), also I've added a checking of search queryand hashalong with the pathname

在我而言,我不得不让路过的目的是to道具(如本地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);

回答by Nguyên Cát Ph?m

I think you should you atrribute to=nullto set disable a link.

我认为您应该将 atrtribute to=null设置为禁用链接。

See an example at here https://stackoverflow.com/a/44709182/4787879

在此处查看示例 https://stackoverflow.com/a/44709182/4787879