Naviguer par programme à l'aide du routeur react

Avec react-router Je Peux utiliser l'élément Link pour créer des liens qui sont gérés nativement par react router.

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 Navigation mixin, mais puis-je le faire sans mixin?

835
demandé sur George Mauer 2015-06-26 20:38:51

25 réponses

Réagir Routeur v4

Avec V4 de React Router, il existe trois approches que vous pouvez prendre pour le routage programmatique dans les composants.

  1. utilisez le composant withRouter d'ordre supérieur.
  2. utiliser la composition et rendre un <Route>
  3. utilisez le context.

Le routeur React est principalement un wrapper autour du history bibliothèque. history gère l'interaction avec le navigateur window.history pour vous avec son navigateur et de hachage histoire. Il fournit également un historique de mémoire 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.

Un history instance a deux méthodes de navigation: push et replace. Si vous considérez le history comme un tableau d'emplacements visités, push ajoutera un nouvel emplacement au tableau et replace remplacera l'emplacement actuel dans le tableau par le nouveau. Typiquement, vous voudrez utiliser le push méthode Lorsque vous naviguez.

Dans les versions antérieures de React Router, vous deviez créer votre propre instance history, mais dans v4 le <BrowserRouter>, <HashRouter>, et les composants <MemoryRouter> créeront des instances de navigateur, de hachage et de mémoire pour vous. React Router rend les propriétés et les méthodes de l'instance history associée à votre routeur disponibles via le contexte, sous l'objet router.

1. Utilisez le composantwithRouter d'ordre supérieur

Le composant withRouter d'ordre supérieur injectez l'objet history comme accessoire du composant. Cela vous permet d'accéder aux méthodes push et replace sans avoir à gérer les 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>
))

2. Utiliser la composition et rendre un <Route>

Le composant <Route> n'est pas seulement destiné aux emplacements correspondants. Vous pouvez rendre un itinéraire sans chemin et Il correspondra toujours à l'emplacement actuel. Le composant <Route> passe les mêmes accessoires que withRouter, de sorte que vous pourrez accéder aux méthodes history via le history prop.

import { Route } from 'react-router-dom'

const Button = () => (
  <Route render={({ history}) => (
    <button
      type='button'
      onClick={() => { history.push('/new-location') }}
    >
      Click Me!
    </button>
  )} />
)

3. Utiliser le contexte*

*Mais vous ne devriez probablement pas

La dernière option est celle que vous ne devriez utiliser que si vous vous sentez à l'aise de travailler avec le modèle context de React. Bien que context soit une option, il convient de souligner que context est une API instable et que React a une section pourquoi ne pas utiliser Context dans leur documentation. Donc à utiliser à 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, donc pour la plupart des cas d'utilisation, ils sont vos meilleurs paris.

690
répondu Paul S 2017-11-29 21:18:12

Réagir-Routeur 4.0.0+ Réponse

Dans 4.0 et au-dessus, utilisez l'historique comme accessoire de votre composant.

class Example extends React.Component {
   // use `this.props.history.push('/some/path')` here
};

Réagir-Routeur 3.0.0+ Réponse

Dans 3.0 et au-dessus, utilisez le routeur comme accessoire de votre composant.

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

Réagir-Routeur 2.4.0+ Réponse

Dans 2.4 et au-dessus, 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
};

Réagir-Routeur 2.0.0+ Réponse

Cette version est rétrocompatible avec 1.x donc, il n'y a pas besoin d'un Guide de mise à niveau. Juste en passant par les exemples devrait être assez bon.

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, de sorte que vous pouvez faire des choses comme push, remplacer, etc... Comme:

browserHistory.push('/some/path')

Autres lectures: historiques et Navigation


Réagir-Routeur 1.x. x réponse

Je ne vais pas entrer dans les détails de mise à niveau. Vous pouvez lire à ce sujet dans le Guide de mise à niveau

Le principal changement à propos de la question ici est le changement de Mixin de Navigation à L'historique. Maintenant, il utilise le navigateur historyAPI pour changer d'itinéraire, 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 ce {[11] } provient du projetrackt/history . Pas de React-routeur 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 depuis this.props.history. Il ne sera accessible que pour les composants rendus par votre routeur. Donc, si vous voulez l'utiliser dans des composants enfants, il doit être transmis en tant qu'attribut via props.

Vous peut en savoir plus sur la nouvelle version à leur 1.0.x documentation

Ici une page d'aide spécifiquement sur la navigation en dehors de votre composant

Il recommande de saisir une référence history = createHistory() et d'appeler replaceState à ce sujet.

Réagir-Routeur 0.13.x réponse

Je suis entré dans le même problème et n'ai pu trouver la solution qu'avec le Mixin de Navigation fourni avec react-router.

Voici comment je l'ai fait il

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
};

Réagir-Routeur-Redux

Remarque: Si vous utilisez Redux, un autre projet est appelé Réagir-Routeur-Redux, ce qui vous donne liaisons redux pour ReactRouter, en utilisant un peu la même approche que Réagir-Redux ne

Réagir-Routeur-Redux a quelques méthodes disponible qui permettent une navigation simple à partir de l'intérieur des créateurs d'action. Ceux-ci peuvent être particulièrement utiles pour les personnes qui ont une architecture existante dans React Native, et ils souhaitent utiliser les mêmes modèles dans React Web avec un minimum de surcharge standard.

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>
702
répondu Felipe Skinner 2018-01-30 23:39:45

Réagir-Routeur v2

Pour la version la plus récente (v2.0.0-rc5), la méthode de navigation recommandée consiste à pousser directement sur le singleton d'historique. Vous pouvez le voir en action dans le document naviguant en dehors du document Components .

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 so:

this.props.history.push('/some/path');

Il offre également pushState mais c'est obsolète par Avertissements enregistrés.

Si vous utilisez react-router-redux, Il offre une fonction push que vous pouvez envoyer comme ceci:

import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));

Cependant, cela ne peut être utilisé que pour changer L'URL, pas pour naviguer réellement vers la page.

471
répondu Bobby 2018-03-26 18:50:01

Voici comment faire avec react-router v2.0.0 avec ES6. react-router s'est éloigné de 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
}
38
répondu Alex Miller 2018-03-26 18:40:49

Pour celui-ci, qui ne contrôle pas le côté serveur et à cause de cela utilise hash router V2:

Placez votre history 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 l'utiliser partout!

Votre point d'entrée pour réagir-routeur (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()
  }
})
26
répondu Алексей Володько 2018-03-26 17:29:26

Réagir-Routeur 4.X réponse:

De mon côté, j'aime avoir un seul objet d'histoire que je peux transporter même des composants extérieurs. Ce que j'aime faire, c'est avoir une seule histoire.fichier js que j'importe à la demande, et il suffit de le manipuler.

Il vous suffit de changer BrowserRouter en routeur, et de spécifier l'historique prop. Cela ne change rien pour vous, sauf que vous avez votre propre objet d'historique que vous pouvez manipuler comme vous le souhaitez.

Vous devez installer histoire, la bibliothèque utilisée par react-router.

Exemple d'utilisation, notation ES6:

Histoire.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 effectivement rendu à partir d'un Route composant, vous pouvez également accéder à l'historique d'accessoires, comme ça :

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>;
    }
}
23
répondu Eric Martin 2018-04-16 11:51:58

Attention: 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 1.0.0-rc1 après!

Vous pouvez le faire sans mixins trop.

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 gotcha avec des contextes est qu'il n'est pas accessible sauf si vous définissez le 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éclare accessoires de jeu à chaque fois. Voir https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html

20
répondu Qiming 2018-03-26 18:47:08

J'ai essayé au moins 10 façons de le faire avant que quelque chose ne fonctionne bien!

La réponse de @ Felipe Skinner withRouter était un peu accablante pour moi, et je n'étais pas sûr de vouloir créer de nouveaux noms de classe" ExportedWithRouter".

Voici la plus simple et la plus propre de le faire, circa actuel Réagir-Routeur 3.0.0 et ES6:

Réagir-Routeur 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:

withRouter(Example);
export { Example };

Notez que dans 3.X. x, le <Link> le composant lui-même utilise router.push, donc vous pouvez lui passer tout ce que vous passeriez la balise <Link to=, comme:

   this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'
17
répondu Ben Wheeler 2018-03-26 18:38:05

Réagir Routeur V4

Tl: dr;

if (navigate) {
  return <Redirect to="/" push={true} />
}

La simple et déclarative réponse est que vous devez utiliser <Redirect to={URL} push={boolean} /> en combinaison avec setState()

Push: boolean - lorsque true, la redirection va pousser une nouvelle entrée dans l'historique au lieu de remplacer l'entrée actuelle.


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 ES7 + initialiseurs de propriétés pour l'initialisation de l'état. Regardez ici aussi, si vous êtes intéressé.

13
répondu Lyubomir 2018-03-26 18:51:11

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:

"réagir " routeur": "^2.7.0"

"réagir": "^15.3.1"

Voici mon composant react où j'ai utilisé la navigation programmatique en utilisant react-router:

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;

Voici la configuration pour 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'));
13
répondu Softwareddy 2018-03-26 20:19:34

Peut-être pas la meilleure approche, mais... En utilisant react-router v4, le Typescript suivant pourrait donner une idée à certains.

Dans le composant Rendu ci-dessous, par exemple LoginPage, router l'objet est accessible et il suffit d'appeler router.transitionTo('/homepage') pour naviguer.

Le code de Navigation a été tiré de https://react-router.now.sh/Match .

"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')
);
12
répondu mcku 2016-09-27 21:32:21

Pour faire la navigation par programme, vous devez pousser un nouveau history vers les props.l'histoire votre component, donc quelque chose comme cela peut faire le travail pour vous:

//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;
12
répondu Alireza 2018-03-26 19:50:47

Dans Réagir-Routeur 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);
11
répondu Hossein 2017-10-17 07:35:03

Basé sur la réponse précédente
de José Antonio Postigo et Ben Wheeler
la nouveauté? doit être écrit dans Tapuscrit
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 n'importe quel npm installé aujourd'hui. "réagir " routeur": "^3.0.0" et
"@types/réagir-routeur": "^2.0.41"

7
répondu Dan 2018-03-26 19:41:19

Avec React-Router v4 à l'horizon, il y a maintenant une nouvelle façon de le faire.

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"/>

Réagir-lego{[5]) est un exemple d'application qui montre comment utiliser/mise à jour de réagir-routeur, et il comprend des exemples de tests fonctionnels qui naviguer dans l'application.

7
répondu peter.mouland 2018-04-19 11:53:14

Avec la version React actuelle (15.3), this.props.history.push('/location'); a fonctionné pour moi, mais il a montré l'avertissement suivant:

Navigateur.js:49 Avertissement: [réagir-routeur] props.history et context.history sont obsolètes. Veuillez utiliser context.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;
5
répondu José Antonio Postigo 2018-03-26 19:33:57

Si vous utilisez le hachage ou l'historique du navigateur, vous pouvez faire

hashHistory.push('/login');
browserHistory.push('/login');
5
répondu Zaman Afzal 2018-03-27 12:46:34

Pour utiliser withRouter avec un composant basé sur une classe, essayez quelque chose comme ceci ci-dessous. 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);
5
répondu Janos 2018-05-28 09:02:04

Réagir-Routeur 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"));

Https://www.npmjs.com/package/trippler

4
répondu Garry Taylor 2016-11-03 17:43:59

À réagir routeur v4. Je suis ce deux voies pour acheminer par programme.

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

WithRouter https://reacttraining.com/react-router/core/api/withRouter

4
répondu saiful619945 2018-08-14 06:33:06

Veuillez trouver ci-dessous le code de travail: Comme discuté dans Cet article , c'est une méthode très simple pour naviguer en utilisant 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>
    )
  }
}

Rediriger/> est -

Événement Utilisateur déclaratif Composable - > changement d'état- > re-render

Le composant Register est rendu par React Router, 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 y a deux façons de naviguer par programme avec React Router-et l'histoire.pousser. Ce que vous utilisez dépend principalement de vous et de votre cas d'utilisation spécifique, bien que j'essaie de favoriser la redirection.

4
répondu kiran malvi 2018-09-19 09:23:59

La bonne réponse était pour moi au moment de la rédaction

this.context.router.history.push('/');

Mais vous devez ajouter des PropTypes à votre composant

Header.contextTypes = {
  router: PropTypes.object.isRequired
}
export default Header;

N'oubliez pas d'importer des PropTypes

import PropTypes from 'prop-types';
2
répondu webmaster 2018-03-27 11:44:38

Peut-être pas la meilleure solution mais cela fait le travail:

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 suppression de poste) finira par appeler un déclencheur pour la redirection. Ce n'est pas idéal car vous ajouterez un "trigger" de noeud DOM à votre balisage juste pour que vous puissiez l'appeler facilement en cas de besoin. En outre, vous interagirez directement avec le DOM, ce qui dans un composant React peut ne pas être souhaité.

Pourtant, ce type de redirection n'est pas nécessaire si souvent. Donc un ou deux des liens cachés supplémentaires dans le balisage de votre composant ne feraient pas beaucoup de mal, surtout si vous leur donnez des noms significatifs.

2
répondu neatsu 2018-03-27 11:50:38

S'il arrive de coupler RR4 w / redux via react-router-redux , Utilisez l'action de routage creators 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 asynchrone, importez les créateurs d'actions ci-dessus dans Redux actions et accrochez les composants react à l'aide de mapDispatchToProps.

2
répondu Xlee 2018-05-07 06:43:29

Il suffit simplement d'utiliser this.props.history.push('/where/to/go');

-1
répondu Oka Prinarjaya 2017-09-21 07:26:09