Avec react-router
je peux utiliser l' Link
élément pour créer des liens qui sont gérés nativement par le routeur React.
Je vois en interne que ça appelle this.context.transitionTo(...)
.
Je veux faire une navigation. Pas à partir d'un lien, mais à partir d'une sélection déroulante (à titre d'exemple). Comment puis-je faire cela dans le code? Qu'est-ce que c'est this.context
?
J'ai vu le Navigation
mixin, mais puis-je m'en passer mixins
?
reactjs
react-router
George Mauer
la source
la source
Réponses:
Il y a un nouveau
useHistory
crochet dans React Router> 5.1.0 si vous utilisez React> 16.8.0 et des composants fonctionnels.Avec la v4 de React Router, il existe trois approches que vous pouvez adopter pour le routage programmatique au sein des composants.
withRouter
composant d'ordre supérieur.<Route>
context
.React Router est principalement un wrapper autour de la
history
bibliothèque.history
gère l'interaction avec le navigateurwindow.history
pour vous avec son navigateur et ses historiques de hachage. Il fournit également un historique de la mémoire qui est utile pour les environnements qui n'ont pas d'historique global. Ceci est particulièrement utile dans le développement d'applications mobiles (react-native
) et les tests unitaires avec Node.Une
history
instance a deux méthodes de navigation:push
etreplace
. Si vous considérez lehistory
comme un tableau d'emplacements visités,push
ajoutera un nouvel emplacement au tableau etreplace
remplacera l'emplacement actuel dans le tableau par le nouveau. En règle générale, vous souhaiterez utiliser lapush
méthode lorsque vous naviguez.Dans les versions antérieures de React Router, vous deviez créer votre propre
history
instance, mais dans la version 4<BrowserRouter>
, les composants<HashRouter>
, et<MemoryRouter>
créeront un navigateur, un hachage et des instances de mémoire pour vous. React Router rend les propriétés et les méthodes de l'history
instance associée à votre routeur disponibles via le contexte, sous l'router
objet.1. Utilisez le
withRouter
composant d'ordre supérieurLe
withRouter
composant d'ordre supérieur injectera l'history
objet comme un accessoire du composant. Cela vous permet d'accéder aux méthodespush
etreplace
sans avoir à gérer lescontext
.2. Utilisez la composition et rendez un
<Route>
Le
<Route>
composant n'est pas seulement pour les emplacements correspondants. Vous pouvez rendre un itinéraire sans chemin et il correspondra toujours à l'emplacement actuel . Le<Route>
composant passe les mêmes accessoires quewithRouter
, vous pourrez donc accéder auxhistory
méthodes via l'history
hélice.3. Utilisez le contexte *
Mais vous ne devriez probablement pas
La dernière option est celle que vous ne devez utiliser que si vous vous sentez à l'aise avec le modèle de contexte de React (l'API de contexte de React est stable à partir de la version 16).
1 et 2 sont les choix les plus simples à implémenter, donc pour la plupart des cas d'utilisation, ce sont vos meilleurs paris.
la source
withRouter
au lieu de passerhistory
à travers tous mes composants ?? Gahh, je dois passer plus de temps à lire des documents ...history.push('/new-location')
sans attacher ce comportement à un bouton ou à un autre élément DOM?Unexpected use of 'history' no-restricted-globals
context
n'est plus expérimental à partir de la réaction 16.Vous pouvez utiliser le nouveau
useHistory
crochet sur les composants fonctionnels et naviguer par programme:Dans les versions 4.0 et supérieures, utilisez l'historique comme accessoire de votre composant.
REMARQUE: this.props.history n'existe pas dans le cas où votre composant n'a pas été rendu par
<Route>
. Vous devez utiliser<Route path="..." component={YourComponent}/>
pour avoir this.props.history dans YourComponentDans les versions 3.0 et supérieures, utilisez le routeur comme accessoire de votre composant.
Dans les versions 2.4 et supérieures, utilisez un composant d'ordre supérieur pour obtenir le routeur comme accessoire de votre composant.
Cette version est rétrocompatible avec 1.x, il n'est donc pas nécessaire d'avoir un guide de mise à niveau. Le simple fait de parcourir les exemples devrait suffire.
Cela dit, si vous souhaitez passer au nouveau modèle, il y a un module browserHistory à l'intérieur du routeur auquel vous pouvez accéder avec
import { browserHistory } from 'react-router'
Maintenant, vous avez accès à l'historique de votre navigateur, vous pouvez donc faire des choses comme pousser, remplacer, etc ...
browserHistory.push('/some/path')
Pour en savoir plus: Histoires et navigation
Je n'entrerai pas dans les détails de mise à niveau. Vous pouvez lire à ce sujet dans le Guide de mise à niveau
Le principal changement concernant la question ici est le passage de la navigation mixin à l'historique. Maintenant, il utilise l'historique du navigateurAPI pour changer d'itinéraire, nous allons donc utiliser
pushState()
partir de maintenant.Voici un exemple utilisant Mixin:
Notez que cela
History
vient de rackt / history projet . Pas de React-Router lui-même.Si vous ne voulez pas utiliser Mixin pour une raison quelconque (peut-être à cause de la classe ES6), vous pouvez accéder à l'historique que vous obtenez du routeur
this.props.history
. Il ne sera accessible que pour les composants rendus par votre routeur. Donc, si vous souhaitez l'utiliser dans des composants enfants, il doit être transmis en tant qu'attribut viaprops
.Vous pouvez en savoir plus sur la nouvelle version sur leur documentation 1.0.x
Voici une page d'aide sur la navigation en dehors de votre composant
Il recommande de saisir une référence
history = createHistory()
et d'appelerreplaceState
à cela.J'ai rencontré le même problème et je n'ai trouvé la solution qu'avec le mixage de navigation fourni avec react-router.
Voici comment je l'ai fait
J'ai pu appeler
transitionTo()
sans avoir besoin d'accéder.context
Ou vous pouvez essayer le fantaisie ES6
class
React-Router-Redux a quelques méthodes disponibles qui permettent une navigation simple depuis les créateurs d'actions. Ceux-ci peuvent être particulièrement utiles pour les personnes qui ont une architecture existante dans React Native, et qui souhaitent utiliser les mêmes modèles dans React Web avec un minimum de surcharge.
Explorez les méthodes suivantes:
push(location)
replace(location)
go(number)
goBack()
goForward()
Voici un exemple d'utilisation, avec Redux-Thunk :
./actioncreators.js
./viewcomponent.js
la source
v2.4.0
mais l'approche mentionnée ne fonctionne pas pour moi, mon application ne s'affiche pas du tout et les sorties de la console:Uncaught TypeError: (0 , _reactRouter.withRouter) is not a function
voici le lien vers mon message SO: stackoverflow.com/questions/37306166/…2.6.0
.3.0.x
? Beaucoup de gens semblent utiliser lecontext
chemin.this.props.history
n'existe pas dans le cas où votre composant n'a pas été rendu par<Route>
. Vous devez utiliser<Route path="..." component={YourComponent}/>
d'avoirthis.props.history
dansYourComponent
.Pour la version la plus récente (
v2.0.0-rc5
), la méthode de navigation recommandée consiste à pousser directement sur le singleton historique. Vous pouvez le voir en action dans le document Navigation en dehors des composants .Extrait pertinent:
Si vous utilisez la nouvelle API react-router, vous devez utiliser le
history
fromthis.props
à l'intérieur des composants afin:Il propose également
pushState
mais qui est déconseillé par les avertissements enregistrés.Si vous utilisez
react-router-redux
, il offre unepush
fonction que vous pouvez envoyer comme ceci:Cependant, cela ne peut être utilisé que pour changer l'URL, pas pour naviguer réellement vers la page.
la source
import { browserHistory } from './react-router'
mais crée à la place l'historique en utilisantimport createBrowserHistory from 'history/lib/createBrowserHistory'
. Plus tard, vous pouvez accéder àhistory
partir des accessoires des composants:this.props.history('/some/path')
var browserHistory = require('react-router').browserHistory; browserHistory.goBack();
push
ne change que l'URL, ne change pas réellement la page. Pour ce faire , à la fois, l' importationbrowserHistory
d'react-router
utilisationbrowserHistory.push('/my-cool-path')
. Malheureusement, ce n'est pas super facile à trouver. github.com/reactjs/react-router/blob/master/docs/guides/…react-router
v4Voici comment procéder
react-router v2.0.0
avec ES6 .react-router
s'est éloigné des mixins.la source
history
singleton comme indiqué par @Bobby. Vous pouvez utilisercontext.router
mais vous rendant vraiment difficile à tester l' unité de ces composants instanciation simplement ce composant pas cela dans le contexte.De mon côté, j'aime avoir un seul objet historique que je peux transporter même en dehors des composants. Ce que j'aime faire, c'est avoir un seul fichier history.js que j'importe à la demande et le manipuler.
Il vous suffit de passer
BrowserRouter
au routeur et de spécifier l'accessoire d'historique. Cela ne change rien pour vous, sauf que vous avez votre propre objet historique que vous pouvez manipuler comme vous le souhaitez.Vous devez installer historique , la bibliothèque utilisée par
react-router
.Exemple d'utilisation, notation ES6:
history.js
BasicComponent.js
Si vous devez naviguer à partir d'un composant qui est réellement rendu à partir d'un
Route
composant, vous pouvez également accéder à l'historique à partir d'accessoires, comme ceci:BasicComponent.js
la source
Router
place deBrowserRouter
.BrowserRouter
crée et gère l'history
objet pour vous. Vous ne devriez pas créer par défaut le vôtre, uniquement si vous ["avez besoin d'une intégration approfondie avec des outils de gestion d'état comme Redux."] Reacttraining.com/react-router/web/api/Routerthis.props.history
, je n'ai pas encore trouvé de solution qui puisse m'aider à faire une telle chose dans une classe qui n'est pas un composant ou tout autre outil qui n'est pas construit en tant que composant React auquel vous pouvez transmettre des accessoires. Merci pour vos commentaires :)Pour celui-ci, qui ne contrôle pas le côté serveur et à cause de cela utilise le hachage routeur v2:
Placez votre historique dans un fichier séparé (par exemple, app_history.js ES6):
Et utilisez-le partout!
Votre point d'entrée pour react-router (app.js ES6):
Votre navigation dans n'importe quel composant (ES6):
la source
history
pour l'une ou l'autre approche maintenanttl: dr;
La réponse simple et déclarative est que vous devez utiliser
<Redirect to={URL} push={boolean} />
en combinaison avecsetState()
Exemple complet ici . En savoir plus ici .
PS. L'exemple utilise ES7 + Property Initializers pour initialiser l'état. Regardez ici aussi, si vous êtes intéressé.
la source
withRouter
n'a pas fonctionné lorsque vous êtes déjà sur l'itinéraire en cours de rechargement. Dans notre cas, nous avons dû sélectivement fairesetState
(provoquerreturn <Redirect>
) si déjà sur la route ouhistory.push()
d'ailleurs.Vous pouvez aussi le faire sans mixins.
Le piège avec les contextes est qu'il n'est pas accessible sauf si vous définissez le
contextTypes
sur la classe.Quant au contexte, c'est un objet, comme les accessoires, qui est transmis du parent à l'enfant, mais il est transmis implicitement, sans avoir à redéclarer les accessoires à chaque fois. Voir https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
la source
J'ai essayé au moins 10 façons de le faire avant que quelque chose fonctionne bien!
La
withRouter
réponse de @Felipe Skinner était un peu écrasante pour moi, et je n'étais pas sûr de vouloir créer de nouveaux noms de classe "ExportedWithRouter".Voici la façon la plus simple et la plus propre de le faire, vers React-Router 3.0.0 et ES6 actuels:
ou, si ce n'est pas votre classe par défaut, exportez comme:
Notez que dans 3.xx, le
<Link>
composant lui-même utiliserouter.push
, vous pouvez donc lui transmettre tout ce que vous voulez passer<Link to=
, comme:la source
200 OK
au lieu du30x
code. Comment puis-je résoudre ce problème?Pour ce faire la navigation par programme, vous devez pousser une nouvelle histoire à la props.history dans votre
component
, si quelque chose comme cela peut faire le travail pour vous:la source
Pour les composants ES6 + React, la solution suivante a fonctionné pour moi.
J'ai suivi Felippe skinner, mais j'ai ajouté une solution de bout en bout pour aider les débutants comme moi.
Voici les versions que j'ai utilisées:
Ci-dessous est mon composant react où j'ai utilisé la navigation programmatique en utilisant react-router:
Voici la configuration de mon routeur:
la source
Ce n'est peut-être pas la meilleure approche mais ... En utilisant react-router v4, le Typescript suivant pourrait donner une idée pour certains.
Dans le composant rendu ci-dessous, par exemple
LoginPage
, l'router
objet est accessible et il suffit d'appelerrouter.transitionTo('/homepage')
pour naviguer.Le code de navigation a été extrait de .
"react-router": "^4.0.0-2",
"react": "^15.3.1",
la source
Vous pouvez utiliser
withRouter
etthis.props.history.push
.la source
Pour l'utiliser
withRouter
avec un composant basé sur une classe, essayez quelque chose comme ceci ci-dessous. N'oubliez pas de modifier la déclaration d'exportation à utiliserwithRouter
:import { withRouter } from 'react-router-dom'
la source
basé sur la réponse précédente
de José Antonio Postigo et Ben Wheeler
la nouveauté? doit être écrit en tapuscrit
et utiliser des décorateurs
OU une propriété / un champ statique
avec n'importe quel npm installé aujourd'hui. "react-router": "^ 3.0.0" et
"@ types / react-router": "^ 2.0.41"
la source
avec React-Router v4 à l'horizon, il existe désormais une nouvelle façon de procéder.
react-lego est un exemple d'application qui montre comment utiliser / mettre à jour react-router et il comprend des exemples de tests fonctionnels qui naviguent dans l'application.
la source
Dans réagir le routeur v4. Je poursuis ces deux voies pour router par programmation.
Numéro deux
Pour obtenir l'historique des accessoires, vous devrez peut-être envelopper votre composant avec
la source
Si vous utilisez le hachage ou l'historique du navigateur, vous pouvez le faire
la source
hashHistory.push
, donne Impossible de lire la propriété "push" de undefined. D'où les importez-vous?Avec la version actuelle de React (15.3), cela
this.props.history.push('/location');
fonctionnait pour moi, mais cela montrait l'avertissement suivant:et je l'ai résolu en utilisant
context.router
comme ceci:la source
React-Router V4
si vous utilisez la version 4, vous pouvez utiliser ma bibliothèque (plug Shameless) où vous envoyez simplement une action et tout fonctionne!
trippler
la source
Ceux qui rencontrent des problèmes lors de l'implémentation de ceci sur react-router v4.
Voici une solution de travail pour naviguer dans l'application React à partir d'actions redux.
history.js
App.js / Route.jsx
autre_fichier.js OU fichier redux
Tout cela grâce à ce commentaire: Commentaire sur les problèmes de ReactTraining
la source
S'il arrive de coupler RR4 w / redux via react -router-redux , utilisez également les créateurs d'actions de routage de
react-router-redux
.Si vous utilisez redux thunk / saga pour gérer le flux asynchrone, importez les créateurs d'actions ci-dessus dans des actions redux et hook pour faire réagir les composants à l'aide de mapDispatchToProps pourrait être mieux.
la source
react-router-redux
est obsolète / archivé depuis longtempsVous pouvez également utiliser le
useHistory
crochet dans un composant sans état. Exemple de la documentation.la source
La bonne réponse était pour moi au moment de la rédaction
Mais vous devez ajouter des PropTypes à votre composant
N'oubliez pas d'importer des PropTypes
la source
Ce n'est peut-être pas la meilleure solution, mais cela fait l'affaire:
Fondamentalement, une logique liée à une action (dans ce cas, une post-suppression) finira par appeler un déclencheur de redirection. Ce n'est pas idéal car vous ajouterez un «déclencheur» de noeud DOM à votre balisage juste pour pouvoir l'appeler facilement en cas de besoin. De plus, vous interagirez directement avec le DOM, qui, dans un composant React, peut ne pas être souhaité.
Pourtant, ce type de redirection n'est pas souvent nécessaire. Donc, un ou deux liens cachés supplémentaires dans le balisage de votre composant ne feraient pas autant de mal, surtout si vous leur donnez des noms significatifs.
la source
Cela a fonctionné pour moi, aucune importation spéciale nécessaire:
la source
history
ajouté àprops
lui-même. Cela vient d'une HoC que vous auriez besoin d'importer pour l'utiliser (les composants envoyés directement à parRoute
sont automatiquement enveloppés par cette HoC mais vous avez besoin d'une importation pourRoute
...)utilisez plutôt le hookrouter, l'alternative moderne au react-router
https://www.npmjs.com/package/hookrouter
Pour répondre à la question OP concernant la liaison via la zone de sélection, vous pouvez le faire:
la source
En supposant que vous n'aurez pas besoin de naviguer pendant le rendu initial lui-même (pour lequel vous pouvez utiliser un
<Redirect>
composant), c'est ce que nous faisons dans notre application.Définissez une route vide qui renvoie null, cela vous permettra d'accéder à l'objet historique. Vous devez le faire au niveau supérieur où votre
Router
est défini.Maintenant , vous pouvez faire toutes les choses qui peuvent être faites sur l' histoire comme
history.push()
,history.replace()
,history.go(-1)
etc!la source
react-router-dom: 5.1.2
Ce site comporte 3 pages, toutes affichées dynamiquement dans le navigateur.
Bien que la page ne soit jamais actualisée, notez comment React Router maintient l'URL à jour lorsque vous naviguez sur le site. Cela préserve l'historique du navigateur, garantissant que des éléments comme le bouton de retour et les signets fonctionnent correctement.
Un commutateur examine tous ses éléments enfants et affiche le premier dont le chemin correspond à l'URL actuelle. Utilisez un moment où vous avez plusieurs itinéraires, mais vous voulez qu'un seul d'entre eux soit rendu à la fois
la source
Donc, dans ma réponse, il existe 3 façons différentes de rediriger par programme vers une route. Certaines des solutions ont déjà été présentées mais les suivantes se concentrent uniquement sur les composants fonctionnels avec une application de démonstration supplémentaire.
En utilisant les versions suivantes:
Configuration:
Donc, tout d'abord, la solution utilise
HashRouter
, configurée comme suit:De la documentation sur
<HashRouter>
:Solutions:
<Redirect>
pour pousser en utilisantuseState
:En utilisant dans un composant fonctionnel (
RedirectPushAction
composant de mon référentiel), nous pouvons utiliseruseState
pour gérer la redirection. La partie délicate est qu'une fois la redirection effectuée, nous devonsredirect
rétablir l' étatfalse
. En utilisantsetTimeOut
avec0
retard, nous attendons que React s'engageRedirect
dans le DOM, puis récupérons le bouton pour l'utiliser la prochaine fois.Veuillez trouver mon exemple ci-dessous:
De la
<Redirect>
documentation:useHistory
crochet:Dans ma solution, il y a un composant appelé
UseHistoryAction
qui représente ce qui suit:withRouter
, obtenir lehistory
deprops
:Créé un composant appelé
WithRouterAction
, s'affiche comme ci-dessous:Lecture de la
withRouter
documentation:Démo:
Pour une meilleure représentation, j'ai construit un référentiel GitHub avec ces exemples, veuillez le trouver ci-dessous:
https://github.com/norbitrial/react-router-programmatically-redirect-examples
J'espère que ça aide!
la source