Wenn Sie auf Browserumgebungen abzielen, müssen Sie react-router-dom
stattdessen package verwenden react-router
. Sie verfolgen den gleichen Ansatz wie React, um den Kern ( react
) und den plattformspezifischen Code ( react-dom
, react-native
) zu trennen , mit dem subtilen Unterschied, dass Sie nicht zwei separate Pakete installieren müssen, sodass die Umgebungspakete alles enthalten du brauchst. Sie können es Ihrem Projekt hinzufügen als:
yarn add react-router-dom
oder
npm i react-router-dom
Das erste, was Sie tun müssen, ist, eine <BrowserRouter>
übergeordnete Komponente in Ihrer Anwendung bereitzustellen . <BrowserRouter>
Verwendet die HTML5- history
API und verwaltet sie für Sie, sodass Sie sich nicht darum kümmern müssen, sie selbst zu instanziieren und <BrowserRouter>
als Requisite an die Komponente weiterzugeben (wie in früheren Versionen erforderlich).
In V4 müssen Sie zum programmgesteuerten Navigieren auf das history
über React verfügbare Objekt zugreifen , context
sofern Sie eine <BrowserRouter>
Anbieterkomponente als oberste übergeordnete Komponente in Ihrer Anwendung haben. Die Bibliothek macht das router
Objekt, das selbst history
eine Eigenschaft enthält, durch den Kontext verfügbar. Die history
Schnittstelle bietet mehrere Navigationsmethoden, wie zum Beispiel push
, replace
und goBack
, unter anderem. Sie können die ganze Liste von Eigenschaften und Methoden überprüfen hier .
Wichtiger Hinweis für Redux / Mobx-Benutzer
Wenn Sie Redux oder Mobx als Statusverwaltungsbibliothek in Ihrer Anwendung verwenden, sind möglicherweise Probleme mit Komponenten aufgetreten, die standortbezogen sein sollten, aber nach dem Auslösen einer URL-Aktualisierung nicht erneut gerendert werden
Das passiert , weil react-router
Pässe location
zu den Komponenten des Kontextmodells.
Sowohl Connect als auch Observer erstellen Komponenten, deren shouldComponentUpdate-Methoden einen flachen Vergleich ihrer aktuellen Requisiten und ihrer nächsten Requisiten durchführen. Diese Komponenten werden nur neu gerendert, wenn mindestens eine Requisite geändert wurde. Dies bedeutet, dass sie eine Requisite erhalten müssen, die sich ändert, wenn sich der Standort ändert, um sicherzustellen, dass sie aktualisiert werden, wenn sich der Standort ändert.
Die 2 Lösungsansätze sind:
- Wickeln Sie Ihre angeschlossene Komponente in einen weglosen
<Route />
. Das aktuelle location
Objekt ist eine der Requisiten, die a <Route>
an die Komponente übergibt, die es rendert
- Wickeln Sie Ihre verbundene Komponente mit der Komponente
withRouter
höherer Ordnung ein, die tatsächlich den gleichen Effekt hat und location
wie eine Requisite injiziert
Abgesehen davon gibt es vier Möglichkeiten, programmgesteuert nach Empfehlungen zu navigieren:
1.- Verwenden einer <Route>
Komponente
Es fördert einen deklarativen Stil. Vor Version 4 wurden
<Route />
Komponenten an die Spitze Ihrer Komponentenhierarchie gesetzt, wobei Sie zuvor über Ihre Routenstruktur nachdenken mussten. Jetzt können Sie jedoch
<Route>
Komponenten an einer
beliebigen Stelle in Ihrem Baum haben, sodass Sie je nach URL eine genauere Steuerung für das bedingte Rendern haben.
Route
einspritzt
match
,
location
und
history
als Requisiten in Ihrer Komponente. Die Navigationsmethoden (wie
push
,
replace
,
goBack
...) werden als Eigenschaften der zur Verfügung stehenden
history
Objekts.
Es gibt 3 Möglichkeiten , etwas mit einem machen Route
, indem man entweder component
, render
oder children
Requisiten, aber nicht verwenden mehr als eine in den gleichen Route
. Die Auswahl hängt vom Anwendungsfall ab, aber im Grunde werden die ersten beiden Optionen Ihre Komponente nur rendern, wenn sie path
mit dem URL-Speicherort übereinstimmt, während mit children
der Komponente gerendert wird, ob der Pfad mit dem Speicherort übereinstimmt oder nicht (nützlich zum Anpassen der Benutzeroberfläche basierend auf der URL passend).
Wenn Sie Ihre Komponente Rendering Ausgabe anpassen möchten , müssen Sie Ihre Komponente in einer Funktion wickeln und verwenden Sie die render
Option, um alle anderen Requisiten , um Ihre Komponente zu übergeben Sie es wünschen, abgesehen von match
, location
und history
. Ein Beispiel zur Veranschaulichung:
import { BrowserRouter as Router } from 'react-router-dom'
const ButtonToNavigate = ({ title, history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
{title}
</button>
);
const SomeComponent = () => (
<Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)
const App = () => (
<Router>
<SomeComponent /> // Notice how in v4 we can have any other component interleaved
<AnotherComponent />
</Router>
);
2.- Verwenden von withRouter
HoC
Diese Komponente höherer Ordnung injiziert die gleichen Requisiten wie Route
. Es beinhaltet jedoch die Einschränkung, dass Sie nur 1 HoC pro Datei haben können.
import { withRouter } from 'react-router-dom'
const ButtonToNavigate = ({ history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
Navigate
</button>
);
ButtonToNavigate.propTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired,
}),
};
export default withRouter(ButtonToNavigate);
3.- Verwenden einer Redirect
Komponente
Wenn Sie a
<Redirect>
rendern, navigieren Sie zu einem neuen Ort. Aber bedenken Sie, dass
standardmäßig die aktuelle Position durch die neue ersetzt wird, wie serverseitige Umleitungen (HTTP 3xx). Der neue Speicherort wird von
to
prop bereitgestellt. Dies kann eine Zeichenfolge (URL, zu der umgeleitet werden soll) oder ein
location
Objekt sein. Wenn Sie stattdessen
einen neuen Eintrag in den Verlauf verschieben möchten , übergeben Sie auch eine
push
Requisite und setzen Sie sie auf
true
<Redirect to="/your-new-location" push />
4.- Manueller Zugriff router
über den Kontext
Ein bisschen entmutigt, da der
Kontext immer noch eine experimentelle API ist und in zukünftigen Versionen von React wahrscheinlich nicht mehr funktioniert
const ButtonToNavigate = (props, context) => (
<button
type="button"
onClick={() => context.router.history.push('/my-new-location')}
>
Navigate to a new location
</button>
);
ButtonToNavigate.contextTypes = {
router: React.PropTypes.shape({
history: React.PropTypes.object.isRequired,
}),
};
Es ist unnötig zu erwähnen, dass es auch andere Router-Komponenten gibt, die für Nicht-Browser-Ökosysteme gedacht sind, z. B. <NativeRouter>
die einen Navigationsstapel im Speicher replizieren und auf die React Native-Plattform abzielen, die über das react-router-native
Paket verfügbar ist .
Für weitere Informationen zögern Sie nicht, die offiziellen Dokumente zu lesen . Es gibt auch ein Video von einem der Co-Autoren der Bibliothek, das eine ziemlich coole Einführung in React-Router v4 bietet und einige der wichtigsten Änderungen hervorhebt.