Quelle est la meilleure façon de rediriger une page à l'aide de React Router?

102

Je suis nouveau sur React Router et j'apprends qu'il existe de nombreuses façons de rediriger une page:

  1. En utilisant browserHistory.push("/path")

    import { browserHistory } from 'react-router';
    //do something...
    browserHistory.push("/path");
  2. En utilisant this.context.router.push("/path")

    class Foo extends React.Component {
        constructor(props, context) {
            super(props, context);
            //do something...
        }
        redirect() {
            this.context.router.push("/path")
        }
    }
    
    Foo.contextTypes = {
        router: React.PropTypes.object
    }
  3. Dans React Router v4, il y a this.context.history.push("/path")et this.props.history.push("/path"). Détails: Comment pousser vers l'historique dans React Router v4?

Je suis tellement confus par toutes ces options, y a-t-il un meilleur moyen de rediriger une page?

Liutong Chen
la source
vous utilisez v4 oui?
azium
1
le lien vers l'autre stack que vous avez posté est assez clair, je recommanderais d'utiliserwithRouter
azium

Réponses:

174

En fait, cela dépend de votre cas d'utilisation.

1) Vous souhaitez protéger votre itinéraire des utilisateurs non autorisés

Si tel est le cas, vous pouvez utiliser le composant appelé <Redirect />et implémenter la logique suivante:

import React from 'react'
import  { Redirect } from 'react-router-dom'

const ProtectedComponent = () => {
  if (authFails)
    return <Redirect to='/login'  />
  }
  return <div> My Protected Component </div>
}

Gardez à l'esprit que si vous voulez <Redirect />travailler comme vous le souhaitez, vous devez le placer à l'intérieur de la méthode de rendu de votre composant afin qu'il soit finalement considéré comme un élément DOM, sinon cela ne fonctionnera pas.

2) Vous souhaitez rediriger après une certaine action (disons après la création d'un élément)

Dans ce cas, vous pouvez utiliser l'historique:

myFunction() {
  addSomeStuff(data).then(() => {
      this.props.history.push('/path')
    }).catch((error) => {
      console.log(error)
    })

ou

myFunction() {
  addSomeStuff()
  this.props.history.push('/path')
}

Afin d'avoir accès à l'historique, vous pouvez envelopper votre composant avec un HOC appelé withRouter. Lorsque vous enveloppez votre composant avec, il passe match locationet se historypropage. Pour plus de détails, veuillez consulter la documentation officielle de withRouter .

Si votre composant est un enfant d'un <Route />composant, à savoir si elle est quelque chose comme <Route path='/path' component={myComponent} />, vous ne devez pas envelopper votre composant avec withRouter, parce que <Route />laissez - passer match, locationet historyà son enfant.

3) Rediriger après avoir cliqué sur un élément

Il y a deux options ici. Vous pouvez utiliser history.push()en le passant à un onClickévénement:

<div onClick={this.props.history.push('/path')}> some stuff </div>

ou vous pouvez utiliser un <Link />composant:

 <Link to='/path' > some stuff </Link>

Je pense que la règle de base avec ce boîtier est d'essayer de l'utiliser en <Link />premier, je suppose surtout à cause des performances.

Cagri Yardimci
la source
Cela fonctionne pour moi `this.props.history.push (" / ");` React-router - v4.2 Merci @Cagri
MD Ashik
stackoverflow.com/questions/60579292/… Pourriez-vous s'il vous plaît jeter un oeil à ces questions?
a125
Dans la dernière option, parce que le composant doit pouvoir le faire historydans ses accessoires this.props.history.push('/path'), cela signifie que le composant est un enfant de <Route/>ou qu'il a un withRouterwrapper dans l'exportation correct?
André
Il est donc possible d'acheminer vers un autre composant sans spécifier <Route path='/path' component={Comp}/>, je suppose que tout simplement render() { return <Comp/>}dans une condition?
André
@Andre oui c'est correct pour l'utilisation de this.props.historymais je ne suis pas sûr si j'ai bien répondu à votre deuxième question? Que voulez-vous dire exactement route to another component?
Cagri Yardimci
6

Maintenant, avec react-router v15.1et au -delà , nous pouvons useHistoryaccrocher, c'est un moyen super simple et clair. Voici un exemple simple du blog source.

import { useHistory } from "react-router-dom";

function BackButton({ children }) {
  let history = useHistory()
  return (
    <button type="button" onClick={() => history.goBack()}>
      {children}
    </button>
  )
}

Vous pouvez l'utiliser dans n'importe quel composant fonctionnel et hooks personnalisés. Et oui, cela ne fonctionnera pas avec les composants de classe comme tout autre hook.

En savoir plus à ce sujet ici https://reacttraining.com/blog/react-router-v5-1/#usehistory

Anand Singh
la source
3

Vous pouvez également utiliser useHistory de la bibliothèque dom du routeur react;

`
import { useHistory } from "react-router-dom";

function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}
`

https://reactrouter.com/web/api/Hooks/usehistory

Maya Liberman
la source
1

Un des moyens les plus simples: utilisez Link comme suit:

import { Link } from 'react-router-dom';

<Link to={`your-path`} activeClassName="current">{your-link-name}</Link>

Si nous voulons couvrir toute la section div sous forme de lien:

 <div>
     <Card as={Link} to={'path-name'}>
         .... 
           card content here
         ....
     </Card>
 </div>
RameshD
la source
0

Vous pouvez également Redirectdans ce Routequi suit. C'est pour gérer les itinéraires invalides.

<Route path='*' render={() => 
     (
       <Redirect to="/error"/>
     )
}/>
Pramuditha
la source