React Router v4 - ¿Cómo obtener la ruta actual?

181

Me gustaría ver una titleen la <AppBar />que de alguna manera se pasa por la ruta actual.

En React Router v4, ¿cómo podría <AppBar />pasar la ruta actual a su titleutilería?

  <Router basename='/app'>
    <main>
      <Menu active={menu} close={this.closeMenu} />
      <Overlay active={menu} onClick={this.closeMenu} />
      <AppBar handleMenuIcon={this.handleMenuIcon} title='Test' />
      <Route path='/customers' component={Customers} />
    </main>
  </Router>

¿Hay una manera de pasar un título personalizado a partir de un encargo propde <Route />?

Raphael Rafatpanah
fuente
Posible duplicado de Cómo obtener la ruta actual en react-router 2.0.0-rc5
Damjan Pavlica

Respuestas:

75

En la versión 5.1 de react-router hay un gancho llamado useLocation , que devuelve el objeto de ubicación actual. Esto puede ser útil en cualquier momento que necesite saber la URL actual.

import { useLocation } from 'react-router-dom'

function HeaderView() {
  let location = useLocation();
  console.log(location.pathname);
  return <span>Path : {location.pathname}</span>
}


vr12
fuente
66
Tenga en cuenta que esto solo se puede usar dentro del DOM del enrutador (es decir, componentes de chid, no en el componente de clase / funcional donde se usa el enrutador). Puede ser obvio, pero no para un novato como yo :-) Recibía todo el tiempo el error "useContext no está definido"
BennyHilarante
Además, esto no funcionará si redirectse utilizó un enrutador . esto leerá el camino antes de la redirección
Sonic Soul
gracias por esta respuesta ...
bellabelle
212

En el router de reacción 4, la ruta actual está en - this.props.location.pathname. Solo obtén this.propsy verifica. Si aún no ve, location.pathnameentonces debe usar el decorador withRouter.

Esto podría verse más o menos así:

import {withRouter} from 'react-router-dom';

const SomeComponent = withRouter(props => <MyComponent {...props}/>);

class MyComponent extends React.Component {
  SomeMethod () {
    const {pathname} = this.props.location;
  }
}
Con Posidielov
fuente
14
tenga en cuenta que esto no siempre es cierto: con react-router4, si su componente se representa en un nivel superior con respecto a algunas rutas anidadas (que extiende la ruta más adelante), la ubicación.nombre de ruta dentro de WithRouter será diferente dewindow.location.pathname
maioman
3
¿Cómo lo conseguimos programáticamente fuera de un componente React?
trusktr
78

Si está utilizando reaccionar de plantillas, donde al final de su apariencia reaccionan de archivo como este: export default SomeComponentes necesario utilizar el componente de orden superior (a menudo referido como un "ESPECIAL"), withRouter.

Primero, necesitarás importar withRouterasí:

import {withRouter} from 'react-router-dom';

A continuación, querrás usar withRouter . Puede hacerlo cambiando la exportación de su componente. Es probable que quieras cambiar de export default ComponentNamea export default withRouter(ComponentName).

Luego puede obtener la ruta (y otra información) de los accesorios. Específicamente, location, match, y history. El código para escupir el nombre de ruta sería:

console.log(this.props.location.pathname);

Una buena reseña con información adicional está disponible aquí: https://reacttraining.com/react-router/core/guides/philosophy

lowcrawler
fuente
Pero, ¿cómo se obtiene la URL completa?
Tessaracter
18

Aquí hay una solución usando history Leer más

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

Router interior

<Router>
   {history.location.pathname}
</Router>
Wael Mohamed BETTAYEB
fuente
3
Para aquellos de nosotros en el camino funcional de reacción, esta respuesta tiene más sentido. Esos this.props....lo que sea es solo ruido para nuestros oídos.
KhoPhi
17

Hay un gancho llamado useLocation en react-router v5, no necesita HOC u otras cosas, es muy sucinto y conveniente.

import { useLocation } from 'react-router-dom';

const ExampleComponent: React.FC = () => {
  const location = useLocation();  

  return (
    <Router basename='/app'>
      <main>
        <AppBar handleMenuIcon={this.handleMenuIcon} title={location.pathname} />
      </main>
    </Router>
  );
}
Alexander Kim
fuente
Esta respuesta debe ser calificada mucho más alta. Usar el gancho es mucho más fácil e intuitivo que estas otras soluciones (si está en RR v5)
BrDaHa
10

Creo que el autor de React Router (v4) acaba de agregar eso con Router HOC para apaciguar a ciertos usuarios. Sin embargo, creo que el mejor enfoque es usar render prop y hacer un componente PropsRoute simple que pase esos accesorios. Esto es más fácil de probar ya que no "conecta" el componente como lo hace withRouter. Tenga un montón de componentes anidados envueltos con Router y no va a ser divertido. Otro beneficio es que también puede usar este pase a través de los accesorios que desee para la ruta. Aquí está el ejemplo simple usando render prop. (más o menos el ejemplo exacto de su sitio web https://reacttraining.com/react-router/web/api/Route/render-func ) (src / components / routes / props-route)

import React from 'react';
import { Route } from 'react-router';

export const PropsRoute = ({ component: Component, ...props }) => (
  <Route
    { ...props }
    render={ renderProps => (<Component { ...renderProps } { ...props } />) }
  />
);

export default PropsRoute;

uso: (aviso para obtener los parámetros de ruta (match.params) puede usar este componente y se los pasará por usted)

import React from 'react';
import PropsRoute from 'src/components/routes/props-route';

export const someComponent = props => (<PropsRoute component={ Profile } />);

También tenga en cuenta que de esta manera puede pasar cualquier accesorio adicional que desee

<PropsRoute isFetching={ isFetchingProfile } title="User Profile" component={ Profile } />
hal9000
fuente
3
¿Hay alguna forma de convertir esta solución en un codepen? Quiero usar la solución más correcta, pero realmente no entiendo cómo implementar.
LAdams87
7

Ha dicho Con Posidielov , la ruta actual está presente en this.props.location.pathname.

Pero si desea hacer coincidir un campo más específico como una clave (o un nombre), puede usar matchPath para encontrar la referencia de ruta original.

import { matchPath } from `react-router`

const routes = [{
  key: 'page1'
  exact: true,
  path: '/page1/:someparam/',
  component: Page1,
},
{
  exact: true,
  key: 'page2',
  path: '/page2',
  component: Page2,
},
]

const currentRoute = routes.find(
  route => matchPath(this.props.location.pathname, route)
)

console.log(`My current route key is : ${currentRoute.key}`)
Rasta_boy
fuente
0

Añadir

import {withRouter} from 'react-router-dom';

Luego cambie su exportación de componentes

export default withRouter(ComponentName)

Luego puede acceder a la ruta directamente dentro del componente en sí (sin tocar nada más en su proyecto) usando:

window.location.pathname

Probado en marzo de 2020 con: "versión": "5.1.2"

Siobhan
fuente
No estoy seguro de este. Claro, está dando el nombre de ruta actual, pero eso no cambia si navego a una nueva página.
alex