React Router v4 - Wie erhalte ich die aktuelle Route?

180

Ich möchte ein titlein anzeigen<AppBar /> , das irgendwie von der aktuellen Route übergeben wurde.

Wie kann in React Router v4 <AppBar />die aktuelle Route an die titleRequisite übergeben werden?

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

Gibt es eine Möglichkeit , einen eigenen Titel von einer Gewohnheit führen propauf <Route />?

Raphael Rafatpanah
quelle
Mögliches Duplikat von Wie man die aktuelle Route in React-Router 2.0.0-rc5 erhält
Damjan Pavlica

Antworten:

74

In der Version 5.1 von React -Router gibt es einen Hook namens useLocation , der das aktuelle Standortobjekt zurückgibt. Dies kann immer dann nützlich sein, wenn Sie die aktuelle URL kennen müssen.

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

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

vjr12
quelle
6
Bitte beachten Sie, dass dies nur im Router-DOM verwendet werden kann (dh Chid-Komponenten, nicht in der Klasse / Funktionskomponente, in der der Router verwendet wird). Es mag offensichtlich sein, aber nicht für einen Neuling wie mich :-) Ich bekam die ganze Zeit den Fehler "useContext is undefined"
BennyHilarious
Auch dies funktioniert nicht, wenn ein Router redirectverwendet wurde. Dies wird den Pfad vor der Weiterleitung lesen
Sonic Soul
danke für diese
antwort
211

In React Router 4 ist die aktuelle Route in - this.props.location.pathname. Einfach abrufen this.propsund überprüfen. Wenn Sie immer noch nicht sehen location.pathname, sollten Sie den Dekorateur verwendenwithRouter .

Das könnte ungefähr so ​​aussehen:

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
quelle
14
Bitte beachten Sie, dass dies nicht immer der Fall ist: Wenn bei React-Router4 Ihre Komponente in Bezug auf einige verschachtelte Routen (die den Pfad später erweitern) auf einer höheren Ebene gerendert wird, unterscheidet sich der window.location.pathname
Name
3
Wie bekommen wir es programmgesteuert außerhalb einer React-Komponente?
Trusktr
78

Wenn Sie die Vorlagen von react verwenden, bei denen das Ende Ihrer React-Datei folgendermaßen aussieht: export default SomeComponentSie müssen die Komponente höherer Ordnung verwenden (häufig als "HOC" bezeichnet) withRouter.

Zuerst müssen Sie wie folgt importieren withRouter:

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

Als nächstes möchten Sie verwenden withRouter . Sie können dies tun, indem Sie den Export Ihrer Komponente ändern. Es ist wahrscheinlich , wollen Sie ändern export default ComponentNamezu export default withRouter(ComponentName).

Dann können Sie die Route (und andere Informationen) von Requisiten erhalten. Insbesondere location, matchund history. Der Code zum Ausspucken des Pfadnamens wäre:

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

Eine gute Beschreibung mit zusätzlichen Informationen finden Sie hier: https://reacttraining.com/react-router/core/guides/philosophy

Lowcrawler
quelle
Aber wie bekommt man die komplette URL?
Tessaracter
18

Hier ist eine Lösung mit history Read more

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

im Router

<Router>
   {history.location.pathname}
</Router>
Wael Mohamed BETTAYEB
quelle
3
Für diejenigen von uns, die sich auf dem Reaktionsweg befinden, ist diese Antwort am sinnvollsten. Diejenigen , this.props....was nur Lärm in unseren Ohren ist.
KhoPhi
17

In React -Router v5 gibt es einen Hook namens useLocation , der weder HOC noch andere Dinge benötigt. Er ist sehr prägnant und praktisch.

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
quelle
Diese Antwort sollte viel höher bewertet werden. Die Verwendung des Hakens ist so viel einfacher und intuitiver als diese anderen Lösungen (wenn auf RR v5)
BrDaHa
10

Ich denke, der Autor von React Router (v4) hat das gerade mit Router HOC hinzugefügt, um bestimmte Benutzer zu beruhigen. Ich glaube jedoch, dass der bessere Ansatz darin besteht, einfach die Render-Requisite zu verwenden und eine einfache PropsRoute-Komponente zu erstellen, die diese Requisiten übergibt. Dies ist einfacher zu testen, da die Komponente nicht wie bei Router "verbunden" wird. Haben Sie eine Reihe verschachtelter Komponenten in Router eingewickelt und es wird keinen Spaß machen. Ein weiterer Vorteil ist, dass Sie diesen Pass auch über beliebige Requisiten zur Route verwenden können. Hier ist das einfache Beispiel mit Render Prop. (so ziemlich das genaue Beispiel von ihrer Website https://reacttraining.com/react-router/web/api/Route/render-func ) (src / components / route / 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;

Verwendung: (Hinweis zum Abrufen der Routenparameter (match.params) Sie können diese Komponente einfach verwenden und diese werden für Sie übergeben.)

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

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

Beachten Sie auch, dass Sie auf diese Weise auch die gewünschten zusätzlichen Requisiten weitergeben können

<PropsRoute isFetching={ isFetchingProfile } title="User Profile" component={ Profile } />
hal9000
quelle
3
Gibt es eine Möglichkeit, diese Lösung in einen Codepen zu verwandeln? Ich möchte die korrektere Lösung verwenden, verstehe aber nicht, wie sie implementiert werden soll.
LAdams87
7

Hat Con Posidielov gesagt, die aktuelle Route ist in vorhanden this.props.location.pathname.

Wenn Sie jedoch einem spezifischeren Feld wie einem Schlüssel (oder einem Namen) entsprechen möchten , können Sie matchPath verwenden , um die ursprüngliche Routenreferenz zu finden.

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

Hinzufügen

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

Ändern Sie dann Ihren Komponentenexport

export default withRouter(ComponentName)

Anschließend können Sie auf die Route direkt innerhalb der Komponente selbst zugreifen (ohne etwas anderes in Ihrem Projekt zu berühren), indem Sie:

window.location.pathname

Getestet im März 2020 mit: "version": "5.1.2"

Siobhan
quelle
Ich bin mir nicht sicher. Sicher, es gibt den aktuellen Pfadnamen an, aber das ändert sich nicht, wenn ich zu einer neuen Seite navigiere.
alex