React Router v4 - Jak uzyskać aktualną trasę?

180

Chciałbym wyświetlić titlein, <AppBar />które zostało w jakiś sposób przekazane z bieżącej trasy.

W jaki sposób w React Router v4 <AppBar />można uzyskać przekazanie bieżącej trasy do jej właściwości title?

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

Czy istnieje sposób, aby zdać niestandardowy tytuł od zwyczaju propna <Route />?

Raphael Rafatpanah
źródło

Odpowiedzi:

74

W wydaniu 5.1 reakcji-routera znajduje się punkt zaczepienia o nazwie useLocation , który zwraca obiekt z bieżącą lokalizacją. Może się to przydać za każdym razem, gdy potrzebujesz znać aktualny adres URL.

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

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

vr12
źródło
6
Należy pamiętać, że może to być używane tylko wewnątrz routera DOM (tj. Komponentów chid, a nie w komponencie klasy / funkcjonalnym, w którym jest używany router). To może być oczywiste, ale nie dla nowicjusza takiego jak ja :-) Cały czas otrzymywałem błąd „useContext is undefined”
BennyHilarious
również to nie zadziała, jeśli redirectbył używany router . to odczyta ścieżkę przed przekierowaniem
Sonic Soul
dziękuję za odpowiedź ...
bellabelle
211

W reakcji router 4 bieżąca trasa znajduje się w - this.props.location.pathname. Po prostu pobierz this.propsi zweryfikuj. Jeśli nadal nie widzisz location.pathname, powinieneś użyć dekoratora withRouter.

Może to wyglądać mniej więcej tak:

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
źródło
14
pamiętaj, że nie zawsze jest to prawdą: w przypadku react-router4, jeśli twój komponent jest renderowany na wyższym poziomie w odniesieniu do niektórych zagnieżdżonych tras (co później rozszerza ścieżkę), location.pathname wewnątrz WithRouter będzie inny niżwindow.location.pathname
maioman
3
Jak uzyskać to programowo poza komponentem React?
trusktr
78

Jeśli używasz reagować'S szablony, gdzie koniec swojego wyglądu plików reagują tak: export default SomeComponenttrzeba użyć komponentu wyższego rzędu (często określane jako „HOC”) withRouter.

Najpierw musisz zaimportować w następujący withRoutersposób:

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

Następnie będziesz chciał użyć withRouter . Możesz to zrobić, zmieniając eksport komponentu. Prawdopodobnie chcesz zmienić z export default ComponentNamena export default withRouter(ComponentName).

Następnie możesz uzyskać trasę (i inne informacje) z rekwizytów. Konkretnie location, matchoraz history. Kod wypluwający nazwę ścieżki wyglądałby tak:

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

Dobry opis z dodatkowymi informacjami jest dostępny tutaj: https://reacttraining.com/react-router/core/guides/philosophy

lowcrawler
źródło
Ale jak uzyskać pełny adres URL?
Tessaracter
18

Oto rozwiązanie wykorzystujące history Czytaj więcej

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

wewnątrz routera

<Router>
   {history.location.pathname}
</Router>
Wael Mohamed BETTAYEB
źródło
3
Dla tych z nas, którzy znajdują się na ścieżce funkcjonalnej reakcji, ta odpowiedź jest najbardziej sensowna. To this.props....wszystko jest tylko hałasem dla naszych uszu.
KhoPhi
17

W React -router v5 jest hak o nazwie useLocation , który nie wymaga HOC ani innych rzeczy, jest bardzo zwięzły i wygodny.

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
źródło
Tę odpowiedź należy ocenić znacznie wyżej. Używanie haka jest o wiele łatwiejsze i intuicyjne niż tych innych rozwiązań (jeśli na RR v5)
BrDaHa
10

Myślę, że autor React Router (v4) właśnie dodał to z Router HOC, aby uspokoić niektórych użytkowników. Uważam jednak, że lepszym podejściem jest po prostu użycie właściwości renderowania i utworzenie prostego komponentu PropsRoute, który przekazuje te właściwości. Jest to łatwiejsze do przetestowania, ponieważ nie „łączy” komponentu, tak jak robi to withRouter. Zapakuj kilka zagnieżdżonych komponentów z routerem i nie będzie to zabawne. Kolejną korzyścią jest to, że możesz również użyć tego przejścia przez dowolne rekwizyty na trasie. Oto prosty przykład użycia właściwości renderowania. (prawie dokładny przykład z ich strony internetowej https://reacttraining.com/react-router/web/api/Route/render-func ) (src / components / tours / 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;

użycie: (uwaga, aby uzyskać parametry trasy (match.params), możesz po prostu użyć tego komponentu, a te zostaną przekazane za Ciebie)

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

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

Zauważ też, że możesz w ten sposób przekazać dowolne dodatkowe rekwizyty

<PropsRoute isFetching={ isFetchingProfile } title="User Profile" component={ Profile } />
hal9000
źródło
3
Czy jest jakiś sposób, abyśmy mogli zamienić to rozwiązanie w kod? Chcę użyć bardziej poprawnego rozwiązania, ale naprawdę nie rozumiem, jak wdrożyć.
LAdams87
7

Ma Con Posidielov powiedział, obecna trasa jest obecny w this.props.location.pathname.

Ale jeśli chcesz dopasować bardziej szczegółowe pole, takie jak klucz (lub nazwa), możesz użyć funkcji matchPath, aby znaleźć oryginalne odwołanie do trasy.

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
źródło
0

Dodaj

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

Następnie zmień eksport komponentu

export default withRouter(ComponentName)

Następnie możesz uzyskać dostęp do trasy bezpośrednio w samym komponencie (bez dotykania niczego innego w projekcie) za pomocą:

window.location.pathname

Testowano w marcu 2020 r. Na: „wersja”: „5.1.2”

Siobhan
źródło
Nie jestem pewien co do tego. Jasne, podaje aktualną ścieżkę, ale to się nie zmieni, jeśli przejdę do nowej strony.
Alex