React Router v4 - Como obter a rota atual?

181

Eu gostaria de exibir um titleem <AppBar />que é de alguma forma passou no da rota atual.

No React Router v4, como seria <AppBar />possível obter a rota atual passada para o seu titleprop?

  <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>

Existe uma maneira de passar um título personalizado a partir de um costume propem <Route />?

Raphael Rafatpanah
fonte
Possível duplicata Como chegar rota atual em reagir roteador 2.0.0-rc5
Damjan Pavlica

Respostas:

75

Na versão 5.1 do react -router, há um gancho chamado useLocation , que retorna o objeto de localização atual. Isso pode ser útil sempre que você precisar conhecer o URL atual.

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

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

vr12
fonte
6
Observe que isso só pode ser usado dentro do DOM do roteador (ou seja, componentes chid, não na classe / componente funcional em que o roteador é usado). Pode ser óbvio, mas não para um novato como eu :-) Eu estava recebendo o tempo todo o erro "useContext é indefinido"
BennyHilarious
também isso não funcionará se um roteador redirectfoi usado. isso lerá o caminho antes do redirecionamento
Sonic Soul
obrigado por esta resposta ...
bellabelle 07/07
212

No roteador de reação 4, a rota atual está em - this.props.location.pathname. Basta obter this.propse verificar. Se você ainda não vê location.pathname, deve usar o decorador withRouter.

Isso pode ser algo como isto:

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
fonte
14
observe que isso nem sempre é verdade: com o react-router4, se o seu componente for renderizado em um nível superior em relação a algumas rotas aninhadas (que estendem o caminho posteriormente), o location.pathname no WithRouter será diferente dewindow.location.pathname
maioman
3
Como podemos obtê-lo programaticamente fora de um componente React?
trusktr
78

Se você estiver usando os modelos do react, onde o final do seu arquivo de reação se parece com o seguinte: export default SomeComponentvocê precisa usar o componente de ordem superior (geralmente chamado de "HOC") withRouter,.

Primeiro, você precisará importar da seguinte withRoutermaneira:

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

Em seguida, você vai querer usar withRouter . Você pode fazer isso alterando a exportação do seu componente. É provável que você queira mudar de export default ComponentNamepara export default withRouter(ComponentName).

Em seguida, você pode obter a rota (e outras informações) dos adereços. Especificamente, location, match, e history. O código para cuspir o nome do caminho seria:

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

Uma boa redação com informações adicionais está disponível aqui: https://reacttraining.com/react-router/core/guides/philosophy

lowcrawler
fonte
Mas como você obtém o URL completo?
Tessaracter 25/12/19
18

Aqui está uma solução usando history Leia mais

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

dentro do roteador

<Router>
   {history.location.pathname}
</Router>
Wael Mohamed BETTAYEB
fonte
3
Para aqueles de nós no caminho funcional de reação, essa resposta faz mais sentido. Aqueles this.props....que são apenas barulho para os nossos ouvidos.
KhoPhi
17

Existe um gancho chamado useLocation no react -router v5, não há necessidade de HOC ou outras coisas, é muito sucinto e 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
fonte
Esta resposta deve ser classificada como muito mais alta. Usar o gancho é muito mais fácil e intuitivo do que essas outras soluções (se estiver no RR v5)
BrDaHa 06/03
10

Acho que os autores do React Router (v4) acabaram de adicionar isso ao Router HOC para apaziguar certos usuários. No entanto, acredito que a melhor abordagem é usar apenas prop prop e criar um simples componente PropsRoute que passe esses props. Isso é mais fácil de testar, pois você não "conecta" o componente como o Router. Tenha um monte de componentes aninhados envolvidos com o Router e não será divertido. Outro benefício é que você também pode usar esse passe através de quaisquer acessórios que desejar para a Rota. Aqui está o exemplo simples usando render prop. (praticamente o exemplo exato do site 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;

use: (aviso para obter os parâmetros de rota (match.params), você pode simplesmente usar este componente e esses serão passados ​​para você)

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

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

Observe também que você também pode passar quaisquer adereços extras que desejar dessa maneira

<PropsRoute isFetching={ isFetchingProfile } title="User Profile" component={ Profile } />
hal9000
fonte
3
Existe alguma maneira de transformar essa solução em um codepen? Quero usar a solução mais correta, mas realmente não entendo como implementar.
precisa saber é o seguinte
7

Tem Con Posidielov disse, a rota atual está presente em this.props.location.pathname.

Mas se você quiser corresponder a um campo mais específico, como uma chave (ou um nome), use matchPath para encontrar a referência de rota 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
fonte
0

Adicionar

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

Em seguida, altere a exportação de componentes

export default withRouter(ComponentName)

Em seguida, você pode acessar a rota diretamente no próprio componente (sem tocar em mais nada no seu projeto) usando:

window.location.pathname

Testado em março de 2020 com: "version": "5.1.2"

Siobhan
fonte
Não tenho certeza sobre este. Claro, está dando o nome do caminho atual, mas isso não muda se eu navegar para uma nova página.
alex