Avec react-router
, je peux utiliser l'élément Link
pour créer des liens qui sont nativement gérés par react-router.
Je vois qu'en interne il appelle this.context.transitionTo(...)
.
Je veux faire une navigation, mais pas à partir d'un lien, à partir d'une sélection déroulante par exemple. Comment puis-je faire cela en code ? Qu'est-ce que this.context
?
J'ai vu le mixin Navigation
, mais puis-je faire cela sans mixins ?
Réponse de React-Router 5.1.0+ (utilisant des hooks et React >16.8)
Vous pouvez utiliser le nouveau hook useHistory
sur les composants fonctionnels et la navigation programmée :
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
// use history.push('/some/path') here
};
React-Router 4.0.0+ Réponse
Dans les versions 4.0 et supérieures, utilisez l'historique comme une propriété de votre composant.
class Example extends React.Component {
// use `this.props.history.push('/some/path')` here
};
NOTE : 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={VotreComposant}/>
pour avoir this.props.history dans VotreComposant.
React-Router 3.0.0+ Réponse
Dans les versions 3.0 et supérieures, utilisez le routeur comme une prop de votre composant.
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
React-Router 2.4.0+ Réponse
Dans les versions 2.4 et supérieures, utilisez un composant d'ordre supérieur pour obtenir le routeur en tant que prop de votre composant.
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
var DecoratedExample = withRouter(Example);
// PropTypes
Example.propTypes = {
router: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
}).isRequired
};
React-Router 2.0.0+ Réponse
Cette version est rétrocompatible avec la version 1.x, il n’y a donc pas besoin d’un guide de mise à niveau. La lecture des exemples devrait suffire.
Cela dit, si vous souhaitez passer au nouveau modèle, il y a un module browserHistory dans le routeur auquel vous pouvez accéder avec la commande suivante
`import { browserHistory } from 'react-router'``
Maintenant vous avez accès à l'historique de votre navigateur, donc vous pouvez faire des choses comme pousser, remplacer, etc... Comme :
browserHistory.push('/some/path' ;)
Plus de lecture : Histoires et Navigation
React-Router 1.x.x Réponse
Je ne vais pas entrer dans les détails de la mise à niveau. Vous pouvez consulter le [Guide de mise à niveau] (https://github.com/rackt/react-router/blob/master/upgrade-guides/v1.0.0.md).
Le principal changement concernant la question posée ici est le passage du mixin Navigation à History. Il utilise maintenant l'API historique du navigateur pour changer d'itinéraire, nous utiliserons donc pushState()
à partir de maintenant.
Voici un exemple utilisant Mixin :
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
Notez que cette Histoire
provient du projet rackt/history. 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), alors vous pouvez accéder à l'historique que vous obtenez du routeur depuis this.props.history
. Il ne sera accessible que pour les composants rendus par votre routeur. Donc, si vous voulez l'utiliser dans un composant enfant, il doit être transmis comme un attribut via props
.
Pour en savoir plus sur la nouvelle version, consultez la [documentation 1.0.x] (https://github.com/rackt/react-router/tree/1.0.x/docs).
Voici [une page d'aide spécifique à la navigation en dehors de votre composant] (https://github.com/rackt/react-router/blob/1.0.x/docs/guides/advanced/NavigatingOutsideOfComponents.md)
Elle recommande de prendre une référence history = createHistory()
et d'appeler replaceState
sur celle-ci.
React-Router 0.13.x Réponse
J'ai rencontré le même problème et je n'ai pu trouver la solution qu'avec le mixin Navigation fourni avec react-router.
Voici comment j'ai procédé
import React from 'react';
import {Navigation} from 'react-router';
let Authentication = React.createClass({
mixins: [Navigation],
handleClick(e) {
e.preventDefault();
this.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
J'ai pu appeler transitionTo()
sans avoir besoin d'accéder à .context
.
Vous pouvez aussi essayer la classe ES6.
import React from 'react';
export default class Authentication extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
}
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
}
Authentication.contextTypes = {
router: React.PropTypes.func.isRequired
};
React-Router-Redux
Note: si vous utilisez Redux, il existe un autre projet appelé React-Router-Redux qui vous donne des liaisons Redux pour ReactRouter, en utilisant un peu la même approche que celle utilisée par React-Router. [React-Redux] (https://github.com/rackt/react-redux).
React-Router-Redux dispose de quelques méthodes qui permettent une navigation simple à partir des créateurs d'actions. Ces méthodes peuvent être particulièrement utiles pour les personnes qui disposent d'une architecture existante dans React Native et qui souhaitent utiliser les mêmes modèles dans React Web avec un minimum d'encombrement.
Explorez les méthodes suivantes :
push(location)
replace(location)
goBack()
goForward()
Voici un exemple d'utilisation, avec Redux-Thunk :
./actioncreators.js
import { goBack } from 'react-router-redux'
export const onBackPress = () => (dispatch) => dispatch(goBack())
./viewcomponent.js
<button
disabled={submitting}
className="cancel_button"
onClick={(e) => {
e.preventDefault()
this.props.onBackPress()
}}
>
CANCEL
</button>
React-Router v2
Pour la version la plus récente (v2.0.0-rc5
), la méthode de navigation recommandée est de pousser directement sur le singleton d'historique. Vous pouvez voir cela en action dans le Naviguer en dehors des composants doc.
Extrait pertinent :
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
Si vous utilisez la nouvelle API react-router, vous devez utiliser le history
de this.props
à l'intérieur des composants :
this.props.history.push('/some/path');
Il offre également pushState
mais il est déprécié par les avertissements enregistrés.
Si vous utilisez react-router-redux
, il offre une fonction push
que vous pouvez distribuer comme ceci :
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
Cependant, cette fonction ne doit être utilisée que pour changer l'URL, et non pour naviguer vers la page.
Avertissement: cette réponse ne couvre que les versions de ReactRouter antérieures à 1.0
Je mettrai à jour cette réponse avec les cas d'utilisation de la version 1.0.0-rc1 après !
Vous pouvez aussi le faire sans mixins.
let Authentication = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
Le problème avec les contextes est qu'ils ne sont pas accessibles à moins que vous ne définissiez les contextTypes
sur la classe.
Quant à ce qu'est le contexte, c'est un objet, comme les props, qui est transmis de parent à enfant, mais il est transmis implicitement, sans avoir à redéclarer les props à chaque fois. Voir https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html