Wenn Sie auf Browserumgebungen abzielen, müssen Sie react-router-domstattdessen 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- historyAPI 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 , contextsofern Sie eine <BrowserRouter> Anbieterkomponente als oberste übergeordnete Komponente in Ihrer Anwendung haben. Die Bibliothek macht das routerObjekt, das selbst historyeine Eigenschaft enthält, durch den Kontext verfügbar. Die historySchnittstelle bietet mehrere Navigationsmethoden, wie zum Beispiel push, replaceund 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-routerPässe locationzu 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 locationObjekt ist eine der Requisiten, die a <Route>an die Komponente übergibt, die es rendert
- Wickeln Sie Ihre verbundene Komponente mit der Komponente
withRouterhöherer Ordnung ein, die tatsächlich den gleichen Effekt hat und locationwie 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.
Routeeinspritzt
match,
locationund
historyals Requisiten in Ihrer Komponente. Die Navigationsmethoden (wie
push,
replace,
goBack...) werden als Eigenschaften der zur Verfügung stehenden
historyObjekts.
Es gibt 3 Möglichkeiten , etwas mit einem machen Route, indem man entweder component, renderoder childrenRequisiten, 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 pathmit dem URL-Speicherort übereinstimmt, während mit childrender 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 renderOption, um alle anderen Requisiten , um Ihre Komponente zu übergeben Sie es wünschen, abgesehen von match, locationund 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 withRouterHoC
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 RedirectKomponente
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
toprop bereitgestellt. Dies kann eine Zeichenfolge (URL, zu der umgeleitet werden soll) oder ein
locationObjekt sein. Wenn Sie stattdessen
einen neuen Eintrag in den Verlauf verschieben möchten , übergeben Sie auch eine
pushRequisite 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-nativePaket 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.