Avec react-router
, je peux utiliser l'élément Link
pour créer des liens qui sont gérés de manière native par le routeur de réaction.
Je vois en interne qu'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 dans le code? Qu'est-ce que this.context
?
J'ai vu le mixin Navigation
, mais puis-je le faire sans mixins?
React Router v4
Avec v4 of React Router, il existe trois approches possibles pour le routage par programmation au sein des composants.
withRouter
d'ordre supérieur.<Route>
_context
.React Router est principalement un wrapper autour de la bibliothèque history
. history
gère les interactions avec le navigateur window.history
avec son navigateur et ses historiques de hachage. Il fournit également un historique de la mémoire utile pour les environnements qui n’ont pas d’historique global. Ceci est particulièrement utile pour le développement d'applications mobiles (_react-native
_) et les tests unitaires avec Node.
Une instance history
a deux méthodes de navigation: Push
et replace
. Si vous pensez que history
est un tableau d'emplacements visités, Push
ajoutera un nouvel emplacement au tableau et replace
remplacera l'emplacement actuel du tableau par le nouveau. Généralement, vous souhaiterez utiliser la méthode Push
lorsque vous naviguez.
Dans les versions antérieures de React Router, vous deviez créer votre propre instance history
, mais dans la v4, les composants _<BrowserRouter>
_, _<HashRouter>
_ et _<MemoryRouter>
_ créeraient un navigateur. hash et instances de mémoire pour vous. React Router rend disponibles les propriétés et les méthodes de l'instance history
associée à votre routeur par le biais du contexte, sous l'objet router
.
withRouter
d'ordre supérieurLe composant d'ordre supérieur withRouter
injectera l'objet history
en tant qu'accessoire du composant. Cela vous permet d'accéder aux méthodes Push
et replace
sans avoir à vous occuper de context
.
_import { withRouter } from 'react-router-dom'
// this also works with react-router-native
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.Push('/new-location') }}
>
Click Me!
</button>
))
_
<Route>
_Le composant _<Route>
_ ne se limite pas aux emplacements correspondants. Vous pouvez rendre un itinéraire sans chemin et il correspondra toujours à l'emplacement actuel . Le composant _<Route>
_ transmet les mêmes accessoires que withRouter
. Vous pourrez ainsi accéder aux méthodes history
par le biais de history
prop.
_import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.Push('/new-location') }}
>
Click Me!
</button>
)} />
)
_
Mais vous ne devriez probablement pas
La dernière option est celle que vous ne devriez utiliser que si vous vous sentez à l'aise avec le modèle contexte de React. Bien que le contexte soit une option, il convient de souligner que le contexte est une API instable et que React a une section Pourquoi ne pas utiliser le contexte dans sa documentation. Alors utilisez à vos risques et périls!
_const Button = (props, context) => (
<button
type='button'
onClick={() => {
// context.history.Push === history.Push
context.history.Push('/new-location')
}}
>
Click Me!
</button>
)
// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
history: React.PropTypes.shape({
Push: React.PropTypes.func.isRequired
})
}
_
1 et 2 sont les choix les plus simples à mettre en œuvre. Par conséquent, dans la plupart des cas, ce sont vos meilleurs choix.
React-Router 4.0.0 + Réponse
Dans les versions 4.0 et supérieures, utilisez l'historique comme accessoire de votre composant.
class Example extends React.Component {
// use `this.props.history.Push('/some/path')` here
};
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 YourComponent
React-Router 3.0.0 + Réponse
Dans les versions 3.0 et supérieures, utilisez le routeur comme accessoire 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 comme accessoire 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étro-compatible avec 1.x, vous n'avez donc pas besoin d'un Guide de mise à niveau. Il suffit de passer en revue les exemples.
Cela dit, si vous souhaitez passer au nouveau modèle, il existe un module browserHistory dans le 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 Push, remplacer, etc.
browserHistory.Push('/some/path')
Lectures supplémentaires: Histoires et Navigation
React-Router 1.x.x Réponse
Je n'entrerai pas dans les détails de la mise à niveau. Vous pouvez lire à ce sujet dans le Guide de mise à nivea
Le principal changement concernant la question ici est le passage du mixage Navigation à l’historique. Maintenant, il utilise historyAPI dans le navigateur pour changer de route. Nous allons donc utiliser pushState()
à partir de maintenant.
Voici un exemple utilisant Mixin:
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
Notez que cette History
provient de rackt/history project. Pas de React-Router lui-même.
Si vous ne souhaitez 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 à partir de this.props.history
. Il ne sera accessible que pour les composants rendus par votre routeur. Donc, si vous voulez l’utiliser dans n’importe quel composant enfant, il doit être transmis comme attribut via props
.
Vous pouvez en savoir plus sur la nouvelle version à leur documentation 1.0.x
Voici ne page d’aide spécifiquement consacrée à la navigation en dehors de votre composant
Il est recommandé de saisir une référence history = createHistory()
et d’appeler replaceState
dessus.
React-Router 0.13.x Réponse
J'ai eu le même problème et je n'ai trouvé que la solution avec le mix de navigation fourni avec react-router.
Voici comment je l'ai fait
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
Ou vous pouvez essayer la fantaisie ES6 class
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
Remarque: si vous utilisez Redux, il existe un autre projet appelé React-Router-Redux qui vous fournit des liaisons redux pour ReactRouter, en utilisant à peu près la même approche que React-Redux
React-Router-Redux dispose de quelques méthodes permettant une navigation simple depuis les créateurs d’actions internes. Celles-ci peuvent être particulièrement utiles pour les personnes qui ont une architecture existante dans React Native et souhaitent utiliser les mêmes modèles dans React Web avec un minimum de temps système.
Explorez les méthodes suivantes:
Push(location)
replace(location)
go(number)
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 consiste à appuyer directement sur le singleton d'historique. Vous pouvez voir cela en action dans le = Navigation en dehors de la documentation sur les composants .
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
lorsque vous vous trouvez dans des composants, par exemple:
this.props.history.Push('/some/path');
Il propose également pushState
mais il est déconseillé pour les avertissements enregistrés.
Si vous utilisez react-router-redux
, il offre une fonction Push
que vous pouvez envoyer comme suit:
import { Push } from 'react-router-redux';
this.props.dispatch(Push('/some/path'));
Toutefois, cela peut uniquement être utilisé pour modifier l'URL, pas pour accéder à la page.
Voici comment procéder avec react-router v2.0.0
avec ES6 . _react-router
_ s'est éloigné des mixins.
_import React from 'react';
export default class MyComponent extends React.Component {
navigateToPage = () => {
this.context.router.Push('/my-route')
};
render() {
return (
<button onClick={this.navigateToPage}>Go!</button>
);
}
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
}
_
React-Router 4.x Réponse:
De mon côté, j'aime bien n'avoir qu'un seul objet d'historique que je puisse porter, même en dehors des composants. Ce que j'aime faire, c’est d’avoir un seul fichier history.js que je peux importer à la demande et de le manipuler.
Il vous suffit de changer BrowserRouter
en Routeur et de spécifier l'historique prop. Cela ne change rien pour vous si ce n'est que vous avez votre propre objet d'historique que vous pouvez manipuler à votre guise.
Vous devez installer history , la bibliothèque utilisée par react-router
.
Exemple d'utilisation, notation ES6:
history.js
import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()
BasicComponent.js
import React, { Component } from 'react';
import history from './history';
class BasicComponent extends Component {
goToIndex(e){
e.preventDefault();
history.Push('/');
}
render(){
return <a href="#" onClick={this.goToIndex}>Previous</a>;
}
}
EDIT 16 avril 2018:
Si vous devez naviguer à partir d'un composant qui est réellement rendu à partir d'un composant Route
, vous pouvez également accéder à l'historique à partir d'accessoires, comme ceci:
BasicComponent.js
import React, { Component } from 'react';
class BasicComponent extends Component {
navigate(e){
e.preventDefault();
this.props.history.Push('/url');
}
render(){
return <a href="#" onClick={this.navigate}>Previous</a>;
}
}
Pour celui-ci, qui ne contrôle pas le côté serveur et utilise pour cette raison le routeur de hachage v2:
Placez votre historique dans un fichier séparé (par exemple, app_history.js ES6):
import { useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });
export default appHistory;
Et utilisez-le partout!
Votre point d'entrée pour react-router (app.js ES6):
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Redirect } from 'react-router'
import appHistory from './app_history'
...
const render((
<Router history={appHistory}>
...
</Router>
), document.querySelector('[data-role="app"]'));
Votre navigation dans n'importe quel composant (ES6):
import appHistory from '../app_history'
...
ajaxLogin('/login', (err, data) => {
if (err) {
console.error(err); // login failed
} else {
// logged in
appHistory.replace('/dashboard'); // or .Push() if you don't need .replace()
}
})
React Router V4
tl: dr;
if (navigate) {
return <Redirect to="/" Push={true} />
}
La réponse simple et déclarative est que vous devez utiliser <Redirect to={URL} Push={boolean} />
en combinaison avec setState()
Push: boolean - lorsque la valeur est true, la redirection insère une nouvelle entrée dans l'historique au lieu de remplacer celle en cours.
import { Redirect } from 'react-router'
class FooBar extends React.Component {
state = {
navigate: false
}
render() {
const { navigate } = this.state
// here is the important part
if (navigate) {
return <Redirect to="/" Push={true} />
}
// ^^^^^^^^^^^^^^^^^^^^^^^
return (
<div>
<button onClick={() => this.setState({ navigate: true })}>
Home
</button>
</div>
)
}
}
Exemple complet ici . Lire la suite ici .
PS. L'exemple utilise initialiseurs de propriété ES7 + pour initialiser l'état. Regardez ici aussi, si cela vous intéresse.
Attention: cette réponse couvre uniquement les versions de ReactRouter antérieures à 1.0
Je mettrai à jour cette réponse avec les cas d'utilisation 1.0.0-rc1 après!
Vous pouvez le faire sans mixins aussi.
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'il n'est accessible que si vous définissez la contextTypes
sur la classe.
En ce qui concerne le contexte, il s’agit d’un objet, comme les accessoires, qui sont transmis de parent à enfant, mais de manière implicite, sans avoir à redéclarer les accessoires à chaque fois. Voir https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
J'ai essayé au moins 10 façons de faire cela avant que quelque chose fonctionne correctement!
La réponse de withRouter
de @Felipe Skinner a été un peu accablante pour moi, et je n'étais pas sûre de vouloir créer de nouveaux noms de classe "ExportedWithRouter".
Voici le moyen le plus simple et le plus propre de le faire, à peu près actuel, React-Router 3.0.0 et ES6:
React-Router 3.x.x avec ES6:
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.Push('/some/path')` here
};
// Export the decorated class
export default withRouter(Example);
ou, si ce n'est pas votre classe par défaut, exportez comme ceci:
withRouter(Example);
export { Example };
Notez que dans 3.x.x, le composant <Link>
utilise lui-même router.Push
, de sorte que vous pouvez le transmettre comme vous le feriez avec la balise <Link to=
, comme ceci:
this.props.router.Push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'
Pour faire la navigation par programmation, vous devez envoyer un nouveau historique au props.history dans votre component
, afin que ce type de travail puisse faire le travail à votre place. :
//using ES6
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
handleClick(e) {
e.preventDefault()
/* Look at here, you can add it here */
this.props.history.Push('/redirected');
}
render() {
return (
<div>
<button onClick={this.handleClick}>
Redirect!!!
</button>
</div>
)
}
}
export default App;
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:
"react-router": "^ 2.7.0"
"réagir": "^ 15.3.1"
Ci-dessous se trouve mon composant de réaction où j'ai utilisé la navigation programmatique à l’aide de réacteur-routeur:
import React from 'react';
class loginComp extends React.Component {
constructor( context) {
super(context);
this.state = {
uname: '',
pwd: ''
};
}
redirectToMainPage(){
this.context.router.replace('/home');
}
render(){
return <div>
// skipping html code
<button onClick={this.redirectToMainPage.bind(this)}>Redirect</button>
</div>;
}
};
loginComp.contextTypes = {
router: React.PropTypes.object.isRequired
}
module.exports = loginComp;
Ci-dessous la configuration de mon routeur:
import { Router, Route, IndexRedirect, browserHistory } from 'react-router'
render(<Router history={browserHistory}>
<Route path='/' component={ParentComp}>
<IndexRedirect to = "/login"/>
<Route path='/login' component={LoginComp}/>
<Route path='/home' component={HomeComp}/>
<Route path='/repair' component={RepairJobComp} />
<Route path='/service' component={ServiceJobComp} />
</Route>
</Router>, document.getElementById('root'));
Veuillez trouver ci-dessous le code de travail: Comme indiqué dans cet article , il est très simple de naviguer à l'aide de react Router:
class Register extends React.Component {
state = {
toDashboard: false,
}
handleSubmit = (user) => {
saveUser(user)
.then(() => this.setState(() => ({
toDashboard: true
})))
}
render() {
if (this.state.toDashboard === true) {
return <Redirect to='/dashboard' />
}
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
< Redirect /> est
Composable ✅ Déclaratif event événement utilisateur -> changement d'état -> re-rendu
Le composant Register est rendu par le routeur React, notre code pourrait ressembler à ceci
class Register extends React.Component {
handleSubmit = (user) => {
saveUser(user).then(() =>
this.props.history.Push('/dashboard')
))
}
render() {
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
en ajoutant withRouter, cela ressemblerait à ceci
import {
withRouter
} from 'react-router-dom'
class Register extends React.Component {
handleSubmit = (user) => {
saveUser(user).then(() =>
this.props.history.Push('/dashboard')
))
}
render() {
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
export default withRouter(Register)
Il existe deux manières de naviguer par programme avec React Router - et history.Push. Ce que vous utilisez dépend principalement de vous et de votre cas d'utilisation spécifique, bien que j'essaie de privilégier la redirection.
Ce n'est peut-être pas la meilleure approche mais ... À l'aide de react-router v4, le TypeScript suivant pourrait en donner une idée.
Dans le composant rendu ci-dessous, par ex. LoginPage
, router
l'objet est accessible et il suffit d'appeler router.transitionTo('/homepage')
pour naviguer.
Le code de navigation a été pris de .
"react-router": "^4.0.0-2",
"react": "^15.3.1",
import Router from 'react-router/BrowserRouter';
import { History } from 'react-history/BrowserHistory';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
interface MatchWithPropsInterface {
component: typeof React.Component,
router: Router,
history: History,
exactly?: any,
pattern: string
}
class MatchWithProps extends React.Component<MatchWithPropsInterface,any> {
render() {
return(
<Match {...this.props} render={(matchProps) => (
React.createElement(this.props.component, this.props)
)}
/>
)
}
}
ReactDOM.render(
<Router>
{({ router }) => (
<div>
<MatchWithProps exactly pattern="/" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/login" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/homepage" component={HomePage} router={router} history={history} />
<Miss component={NotFoundView} />
</div>
)}
</Router>,
document.getElementById('app')
);
Dans React-Router v4 et ES6
Vous pouvez utiliser withRouter
et this.props.history.Push
.
import {withRouter} from 'react-router-dom';
class Home extends Component {
componentDidMount() {
this.props.history.Push('/redirect-to');
}
}
export default withRouter(Home);
Pour utiliser withRouter
avec un composant basé sur une classe, essayez l'une des solutions suivantes. N'oubliez pas de changer l'instruction d'exportation pour utiliser withRouter
:
import { withRouter } from 'react-router-dom'
class YourClass extends React.Component {
yourFunction = () => {
doSomeAsyncAction(() =>
this.props.history.Push('/other_location')
)
}
render() {
return (
<div>
<Form onSubmit={ this.yourFunction } />
</div>
)
}
}
export default withRouter(YourClass);
Dans réagir routeur v4. Je suis cette double façon de route par programmation.
1. this.props.history.Push("/something/something")
2. this.props.history.replace("/something/something")
Numéro deux
Remplace l'entrée actuelle sur la pile d'historique
Pour obtenir l'historique dans les accessoires, vous devrez peut-être envelopper votre composant avec
basé sur la réponse précédente
de José Antonio Postigo et Ben Wheeler
la nouveauté? doit être écrit en TypeScript
et l'utilisation de décorateurs
OU statique propriété/champ
import * as React from "react";
import Component = React.Component;
import { withRouter } from "react-router";
export interface INavigatorProps {
router?: ReactRouter.History.History;
}
/**
* Note: goes great with mobx
* @inject("something") @withRouter @observer
*/
@withRouter
export class Navigator extends Component<INavigatorProps, {}>{
navigate: (to: string) => void;
constructor(props: INavigatorProps) {
super(props);
let self = this;
this.navigate = (to) => self.props.router.Push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
/**
* Non decorated
*/
export class Navigator2 extends Component<INavigatorProps, {}> {
static contextTypes = {
router: React.PropTypes.object.isRequired,
};
navigate: (to: string) => void;
constructor(props: INavigatorProps, context: any) {
super(props, context);
let s = this;
this.navigate = (to) =>
s.context.router.Push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
avec npm installé aujourd'hui. "react-router": "^ 3.0.0" et
"@ types/react-router": "^ 2.0.41"
avec React-Router v4 à l’horizon, il existe maintenant une nouvelle façon de procéder.
import { MemoryRouter, BrowserRouter } from 'react-router';
const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;
<Router location="/page-to-go-to"/>
react-lego est un exemple d'application montrant comment utiliser/mettre à jour react-router et comprenant des exemples de tests fonctionnels permettant de naviguer dans l'application.
Si vous utilisez l'historique du hachage ou du navigateur, vous pouvez le faire.
hashHistory.Push('/login');
browserHistory.Push('/login');
Avec la version actuelle de React (15.3), this.props.history.Push('/location');
fonctionnait pour moi, mais il contenait l'avertissement suivant:
browser.js: 49 Avertissement: [react-router]
props.history
etcontext.history
sont obsolètes. Veuillez utilisercontext.router
.
et je l'ai résolu en utilisant context.router
comme ceci:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.backPressed = this.backPressed.bind(this);
}
backPressed() {
this.context.router.Push('/back-location');
}
...
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
};
export default MyComponent;
React-Router V4
si vous utilisez la version 4, vous pouvez utiliser ma bibliothèque (Shameless Plug) où vous envoyez simplement une action et tout fonctionne!
dispatch(navigateTo("/aboutUs"));
Ceux qui sont confrontés à des problèmes lors de l’implémentation de ceci sur react-router v4.
Voici une solution de travail pour naviguer dans l'application de réaction des actions redux.
histoire.js
import createHistory from 'history/createBrowserHistory'
export default createHistory()
App.js/Route.jsx
import { Router, Route } from 'react-router-dom'
import history from './history'
...
<Router history={history}>
<Route path="/test" component={Test}/>
</Router>
another_file.js OR fichier redux
import history from './history'
history.Push('/test') // this should change the url and re-render Test component
Tout cela grâce à ce commentaire: commentaire sur les problèmes de ReactTraining
S'il arrive de coupler RR4 avec redux via react-router-redux , utilisez les créateurs d'action de routage de react-router-redux
est également une option.
import { Push, replace, ... } from 'react-router-redux'
class WrappedComponent extends React.Component {
handleRedirect(url, replaceState = true) {
replaceState
? this.props.dispatch(replace(url))
: this.props.dispatch(Push(url))
}
render() { ... }
}
export default connect(null)(WrappedComponent)
Si vous utilisez redux thunk/saga pour gérer le flux async, importez les créateurs d'action ci-dessus dans les actions redux et connectez-vous pour réagir aux composants à l'aide de mapDispatchToProps peut être préférable.
Ce n’est peut-être pas la meilleure solution, mais le travail est fait:
import { Link } from 'react-router-dom';
// create functional component Post
export default Post = () => (
<div className="component post">
<button className="button delete-post" onClick={() => {
// ... delete post
// then redirect, without page reload, by triggering a hidden Link
document.querySelector('.trigger.go-home').click();
}}>Delete Post</button>
<Link to="/" className="trigger go-home hidden"></Link>
</div>
);
Fondamentalement, une logique liée à une action (dans ce cas une post-suppression) finira par appeler un déclencheur pour la redirection. Ce n'est pas idéal car vous allez ajouter un "déclencheur" de nœud DOM à votre balisage afin de pouvoir facilement l'appeler en cas de besoin. De plus, vous interagirez directement avec le DOM, ce qui peut ne pas être souhaité dans un composant React.
Néanmoins, ce type de redirection n’est pas requis aussi souvent. Ainsi, un ou deux liens supplémentaires cachés dans le balisage de votre composant ne feraient pas beaucoup de mal, surtout si vous leur donnez des noms significatifs.
La bonne réponse était pour moi au moment de l'écriture
this.context.router.history.Push('/');
Mais vous devez ajouter PropTypes à votre composant
Header.contextTypes = {
router: PropTypes.object.isRequired
}
export default Header;
N'oubliez pas d'importer des PropTypes
import PropTypes from 'prop-types';
Pour React Router v4 +
En supposant que vous n’ayez pas besoin de naviguer pendant le rendu initial (pour lequel vous pouvez utiliser le composant <Redirect>
], c’est ce que nous faisons dans notre application.
Définissez un itinéraire vide qui renvoie null, cela vous permettra d’obtenir l’accès à l’historique. Vous devez le faire au plus haut niveau où votre Router
est défini.
Maintenant, vous pouvez faire tout ce qui peut être fait sur historique comme history.Push()
, history.replace()
, history.go(-1)
etc!
import React from 'react';
import { HashRouter, Route } from 'react-router-dom';
let routeHistory = null;
export function navigateTo(path) {
if(routeHistory !== null) {
routeHistory.Push(path);
}
}
export default function App(props) {
return (
<HashRouter hashType="noslash">
<Route
render={({ history }) => {
routeHistory = history;
return null;
}}
/>
{/* Rest of the App */}
</HashRouter>
);
}
Cela a fonctionné pour moi, aucune importation spéciale requise:
<input type="button" name="back" id="back" class="btn btn-primary" value="Back" onClick={() => { this.props.history.goBack() }} />