react-router: Cómo deshabilitar un si está activo?

7 minutos de lectura

¿Cómo puedo desactivar un <Link> en react-router, si su URL ya está activa? Por ejemplo, si mi URL no cambiara al hacer clic en <Link> Quiero evitar hacer clic o renderizar un <span> en lugar de un <Link>.

La única solución que se me ocurre es usar activeClassName (o activeStyle) y ajuste pointer-events: none;pero prefiero usar una solución que funcione en IE9 e IE10.

  • stackoverflow.com/a/10276157/1642219

    – Udit Bhardwaj

    12/03/2016 a las 22:10

  • @UDB Representando un <span> en vez de <a> está totalmente bien. Esta pregunta era específica de react-router, no una pregunta general. Pero gracias.

    – Pipo

    13 de marzo de 2016 a las 19:08

Avatar de usuario de Denis Bubnov
Denis Bunov

Puedes usar CSS pointer-events atributo. Esto funcionará con la mayoría de los navegadores. Por ejemplo, su código JS:

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

y CSS:

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

Enlaces:

La respuesta adjunta Cómo deshabilitar los enlaces HTML sugiere usar ambos disabled y pointer-events: none para obtener la máxima compatibilidad con el navegador.

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

Enlace a la fuente: Cómo deshabilitar el enlace

  • Es importante notar que el pointer-events La técnica solo deshabilitará los clics desde un dispositivo de puntero. Todavía es posible seleccionar y activar el enlace con el teclado.

    – Matharden

    8 de octubre de 2021 a las 12:23

  • Este enfoque no es seguro. Un usuario puede traspasar el enlace deshabilitado usando herramientas de desarrollo.

    – Si Jue

    5 de noviembre a las 9:52

Esto funciona para mí:

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

  • donde esta isActive ¿procedente de?

    – Drazen Bjelovuk

    23 de junio de 2020 a las 19:04

  • Viene de props/state.

    – Milen Gardev

    30 de junio de 2020 a las 18:01

  • Se moverá a la parte superior de la página. href="#" es realmente molesto para los usuarios.

    –Kevin Beal

    3 de marzo a las 16:05

  • Esto no deshabilita el componente Enlace, el usuario aún puede hacer clic en el enlace activo de esta manera.

    – huntzinger92

    4 abr a las 20:45

No voy a preguntar por qué querrías este comportamiento, pero supongo que puedes envolver <Link /> en su propio componente de enlace personalizado.

<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, pero probablemente tengas una idea general…)

  • Puedo ver por qué eso sería útil. Si la etiqueta se reemplaza con una etiqueta o , el enlace se convertirá en un elemento en negrita en una lista de migas de pan cuando se haga clic en el enlace. Al hacer clic en otro enlace de migas de pan, se volvería a habilitar la etiqueta para el clic anterior y se aplicaría el estado de enlace en negrita + deshabilitado al enlace en el que se hizo clic recientemente.

    – Clomp

    6 jun 2016 a las 19:01

  • Con react-router v4, debe usar this.props.history.location.pathname en vez de this.props.route

    – nbeuchat

    28 de enero de 2018 a las 2:19

  • También sugiero usar {this.props.children} en lugar de agregar nuevos accesorios linktext. De esta manera, realmente puede usar este componente como un Link componente.

    – nbeuchat

    28 de enero de 2018 a las 2:21

  • Esta solución no es accesible. deberías pasar aria-disabled="true" y quitar el to (aunque Link requiere que lo apruebe) o use preventDefault.

    – SRachamim

    20 de julio de 2020 a las 8:39

  • Mejor use la función matchPath de la biblioteca de enrutador de reacción para verificar si la ruta está activa. La solución antes mencionada no funcionará en todos los casos, así que no confíe en la comparación ===.

    – Sombrilla

    1 ene a las 15:46

Otra posibilidad es deshabilitar el evento de clic si ya se está haciendo clic en la misma ruta. Aquí hay una solución que funciona con 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);

Luego puede usar su enlace como (cualquier accesorio adicional de Link trabajaría):

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

Todos la bondad de Reaccionar enrutador NavLink con el deshabilitar capacidad.

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

  • props no tiene propiedad to y sin firma de índice de cadena.

    – Federico Krautwald

    13 de junio de 2018 a las 12:39

  • No estoy seguro de haber entendido tu comentario, pero ten en cuenta que const Link... es un HOC. También los accesorios son la fusión de withRouter apoyos dados y lo habitual Link accesorios. to pertenece a los accesorios del envuelto Link. PD: NavLink es una versión especial de Link y como tal lleva un to apoyo también. reacttraining.com/react-router/web/api/NavLink

    – fsenart

    13 de junio de 2018 a las 13:15

  • Ah, lo siento, la solución “escrita” está fuera del alcance, prefiero dar una solución más a propósito. Pero no dude en proporcionar una versión mecanografiada con su dialecto de elección.

    – fsenart

    13 de junio de 2018 a las 13:27

Avatar de usuario de Kishan Bharda
Kishan Bharda

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


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

Puedes probar esto, esto funcionó para mí.

  • props no tiene propiedad to y sin firma de índice de cadena.

    – Federico Krautwald

    13 de junio de 2018 a las 12:39

  • No estoy seguro de haber entendido tu comentario, pero ten en cuenta que const Link... es un HOC. También los accesorios son la fusión de withRouter apoyos dados y lo habitual Link accesorios. to pertenece a los accesorios del envuelto Link. PD: NavLink es una versión especial de Link y como tal lleva un to apoyo también. reacttraining.com/react-router/web/api/NavLink

    – fsenart

    13 de junio de 2018 a las 13:15

  • Ah, lo siento, la solución “escrita” está fuera del alcance, prefiero dar una solución más a propósito. Pero no dude en proporcionar una versión mecanografiada con su dialecto de elección.

    – fsenart

    13 de junio de 2018 a las 13:27

Avatar de usuario de Wesss
Wess

Reaccionar del enrutador Route el componente tiene tres maneras diferentes para renderizar contenido basado en la ruta actual. Tiempo component se usa más típicamente para mostrar un componente solo durante un partido, el children componente toma en un ({match}) => {return <stuff/>} devolución de llamada que puede representar cosas encajonadas en el partido incluso cuando las rutas no coinciden.

Creé una clase NavLink que reemplaza un enlace con un lapso y agrega una clase cuando es to la ruta está activa.

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

Luego crea un enlace de navegación así

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

NavLink del enrutador React hace algo similar, pero aún permite al usuario hacer clic en el enlace y enviar el historial.

¿Ha sido útil esta solución?