簡體   English   中英

react-router:如何禁用<link> ,如果它是活躍的?

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

我如何禁用 react-router 中的<Link> ,如果它的 URL 已經激活? 例如,如果我的 URL 在單擊<Link>時不會改變,我想完全阻止單擊或呈現<span>而不是<Link>

我想到的唯一解決方案是使用activeClassName (或activeStyle )並設置pointer-events: none; ,但我寧願使用適用於 IE9 和 IE10 的解決方案。

您可以使用 CSS 的pointer-events屬性。 這將適用於大多數瀏覽器。 例如你的JS代碼:

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

和 CSS:

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

鏈接:

附加的如何禁用 HTML 鏈接答案建議同時使用disabledpointer-events: none以獲得最大的瀏覽器支持。

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

鏈接到源:如何禁用鏈接

我不會問您為什么想要這種行為,但我想您可以將<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,但您可能已經大致了解了...)

這對我有用:

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

另一種可能性是如果已經在同一路徑上單擊,則禁用單擊事件。 這是一個適用於 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);

然后您可以將您的鏈接用作(來自Link任何額外道具都可以使用):

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

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

React Router 的Route組件具有三種不同的方式來基於當前路由呈現內容。 雖然component最常用於僅在匹配期間顯示組件,但children組件接受({match}) => {return <stuff/>}回調,即使路由不匹配,它也可以呈現匹配的內容匹配

我創建了一個 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}/>;
          }
        }}
      />
    );
  }
}

然后像這樣創建一個導航鏈接

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

React Router 的 NavLink做了類似的事情,但它仍然允許用戶點擊鏈接並推送歷史記錄。

基於 nbeuchat 的答案和組件 - 我創建了一個自己的改進版本的組件,它覆蓋了我的項目的react router's Link組件。

在我的情況下,我必須允許將對象傳遞to prop(如本機react-router-dom鏈接所做的那樣),我還添加了對search queryhash以及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);

解決此問題的另一種選擇是使用ConditionalWrapper組件,該組件根據條件呈現<Link>標記。

這是我基於此博客使用的ConditionalWrapper組件https://blog.hackages.io/conditionally-wrap-an-element-in-react-a8b9a47fab2

const ConditionalWrapper = ({ condition, wrapper, children }) =>
    condition ? wrapper(children) : children;

export default ConditionalWrapper

這就是我們使用它的方式:

const SearchButton = () => {
    const {
        searchData,
    } = useContext(SearchContext)

    const isValid = () => searchData?.search.length > 2

    return (<ConditionalWrapper condition={isValid()}
                                wrapper={children => <Link href={buildUrl(searchData)}>{children}</Link>}>
            <a
                className={`ml-auto bg-${isValid()
                    ? 'primary'
                    : 'secondary'} text-white font-filosofia italic text-lg md:text-2xl px-4 md:px-8 pb-1.5`}>{t(
                    'search')}</a>
        </ConditionalWrapper>
    )
}

此解決方案不呈現Link元素,也避免了代碼重復。

... const [isActive, setIsActive] = useState(true); ...

你可以試試這個,這對我有用。

我認為您應該將 atrtribute to=null設置為禁用鏈接。

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

如果它適合你的設計,在它上面放一個 div,然后操作 z-index。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM