Comment passer des paramètres avec history.push / Link / Redirect dans react-router v4?

218

Comment passer un paramètre avec this.props.history.push('/page')dans React-Router v4?

.then(response => {
       var r = this;
        if (response.status >= 200 && response.status < 300) {
             r.props.history.push('/template');
          });
IshanGarg
la source
Le composant qui est rendu par un Routedevrait avoir accès à this.props.location, this.props.historyetc. Je pense que vous n'avez pas besoin d'utiliser refplus avec v4. Essayez de fairethis.props.history.push('/template');
saadq
Ce n'est pas ref, c'est variable qui pointe vers ça; this.props.history.push ('/ template'); amenez-moi à la page suivante mais je veux passer des accessoires avec eux .ref = this;
IshanGarg
Vous essayez de passer propsau composant qui correspond à l'itinéraire? Je pense que ce fil GitHub répond à votre préoccupation.
saadq
JFYI - J'ai supprimé <a href> et ajouté <Link> qui a également l'option d'envoyer l'état, qui peut être consulté par la page suivante via, this.props.location.state.
Manohar Reddy Poreddy
Pourriez-vous s'il vous plaît marquer l'une des réponses comme «réponse». Je suis sûr que les gens qui passent du temps à les taper l'apprécieront.
James Poulose

Réponses:

392

Tout d'abord, vous n'avez pas besoin de le faire var r = this;car cela if statementfait référence au contexte du rappel lui-même qui, puisque vous utilisez la fonction flèche, fait référence au contexte du composant React.

Selon les documents:

Les objets d'historique ont généralement les propriétés et méthodes suivantes:

  • longueur - (nombre) Le nombre d'entrées dans la pile d'historique
  • action - (chaîne) L'action en cours (PUSH, REPLACE ou POP)
  • location - (object) L'emplacement actuel. Peut avoir les propriétés suivantes:

    • chemin - (chaîne) Le chemin de l'URL
    • search - (chaîne) La chaîne de requête URL
    • hachage - (chaîne) Le fragment de hachage URL
    • état - (chaîne) état spécifique à l'emplacement qui a été fourni, par exemple, à push (chemin, état) lorsque cet emplacement a été poussé sur la pile. Disponible uniquement dans l'historique du navigateur et de la mémoire.
  • push (chemin, [état]) - (fonction) Pousse une nouvelle entrée sur la pile d'historique
  • replace (chemin, [état]) - (fonction) Remplace l'entrée actuelle sur la pile d'historique
  • go (n) - (fonction) Déplace le pointeur dans la pile d'historique de n entrées
  • goBack () - (fonction) Équivalent à go (-1)
  • goForward () - (fonction) Équivalent à go (1)
  • block (prompt) - (fonction) Empêche la navigation

Ainsi, pendant la navigation, vous pouvez passer des accessoires à l'objet historique comme

this.props.history.push({
  pathname: '/template',
  search: '?query=abc',
  state: { detail: response.data }
})

ou de même pour le Linkcomposant ou le Redirectcomposant

<Link to={{
      pathname: '/template',
      search: '?query=abc',
      state: { detail: response.data }
    }}> My Link </Link>

puis dans le composant qui est rendu avec /templateroute, vous pouvez accéder aux accessoires passés comme

this.props.location.state.detail

Gardez également à l'esprit que lorsque vous utilisez des objets d'historique ou de localisation à partir d'accessoires, vous devez connecter le composant withRouter.

Selon les documents:

withRouter

Vous pouvez accéder aux propriétés de l'objet historique et à la <Route>'scorrespondance la plus proche via le withRoutercomposant d'ordre supérieur. withRouter rendra son composant à chaque fois que la route change avec les mêmes accessoires que le <Route>rendu props: { match, location, history }.

Shubham Khatri
la source
3
oui, cela a fonctionné. Merci! Mais je ne sais this.props.history.push('/template',response.data)pas pourquoi ne pas travailler. Selon les documents de push(path, [state]), ne pensez-vous pas que cela devrait fonctionner?
Sanket Patel
1
Merci pour cela! Dans mon cas, je ne faisais que passer directement l'histoire, j'ai donc accédé à mon accessoire via this.props.history.location.state.propName -
Nunchucks
@SanketPatel vous devez le faire this.props.history.push ('/ template', {response: response.data})
Arsalan Ahmed Quershi
Est-il possible d'ouvrir l'itinéraire dans un nouvel onglet tout en passant des données dans la variable d'état lors de la navigation, vous pouvez passer des accessoires à l'objet historique?
Gaurav Kumar
3
qu'en est-il de goBack ()? lorsque je reviens avec goBack (), je ne peux voir aucun des états d'historique dans props.location ou props.history.location. Naviguer vers l'avant avec push () cela fonctionne bien
MariusB
40

vous pouvez utiliser,

this.props.history.push("/template", { ...response }) ou this.props.history.push("/template", { response: response })

alors vous pouvez accéder aux données analysées du /templatecomposant en suivant le code,

const state = this.props.location.state

En savoir plus sur React Session History Management

Tenusha Guruge
la source
Cette logique a fonctionné pour moi tandis que history.push avec back_url dans l'état this.props.history.push (redirect_url, {back_url: '/ need_url'}); et obtenir ceci sur la page de destination par this.props.location.state.back_url
Braham Dev Yadav
25
  • Pour les versions antérieures :

    history.push('/path', yourData);

    Et obtenez les données dans le composant associé comme ci-dessous:

    this.props.location.state // it is equal to yourData
  • Pour les versions plus récentes, la méthode ci-dessus fonctionne bien, mais il existe une nouvelle méthode:

    history.push({
      pathname: '/path',
      customNameData: yourData,
    });

    Et obtenez les données dans le composant associé comme ci-dessous:

    this.props.location.customNameData // it is equal to yourData

Astuce : le statenom de la clé a été utilisé dans les versions antérieures et pour les versions plus récentes, vous pouvez utiliser votre nom personnalisé pour transmettre des données et l'utilisation du statenom n'est pas essentielle.

AmerllicA
la source
s'il vous plaît partager la référence, qui dit que l'état n'est pas essentiel, si vous l'avez à portée de main
Akshay Vijay Jain
Cher @AkshayVijayJain, c'est mon expérience de codage. Je n'ai pas écrit cette phrase sur la base d'un doc ou d'une réf.
AmerllicA
22

Extension de la solution (suggérée par Shubham Khatri) pour une utilisation avec les crochets React (à partir de 16,8):

package.json (always worth updating to latest packages)

{
     ...

     "react": "^16.12.0",
     "react-router-dom": "^5.1.2",

     ...
}

Passer des paramètres avec l'historique push:

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

const FirstPage = props => {
    let history = useHistory();

    const someEventHandler = event => {
       history.push({
           pathname: '/secondpage',
           search: '?query=abc',
           state: { detail: 'some_value' }
       });
    };

};

export default FirstPage;

Accès au paramètre passé à l'aide de useLocation à partir de 'react-router-dom':

import { useEffect } from "react";
import { useLocation } from "react-router-dom";

const SecondPage = props => {
    const location = useLocation();

    useEffect(() => {
       console.log(location.pathname); // result: '/secondpage'
       console.log(location.search); // result: '?query=abc'
       console.log(location.state.detail); // result: 'some_value'
    }, [location]);

};
akhouri
la source
Merci beaucoup, je n'ai pas trouvé d'alternative mise à jour, sauf votre réponse!
jamezrin
10

Si vous devez transmettre des paramètres d'URL

theres une grande explication de poste par Tyler McGinnis sur son site, Lien vers le poste

voici des exemples de code:

  1. sur le composant history.push:

    this.props.history.push(`/home:${this.state.userID}`)

  2. sur le composant routeur, vous définissez l'itinéraire:

    <Route path='/home:myKey' component={Home} />

  3. sur le composant Home:

componentDidMount(){
    const { myKey } = this.props.match.params
    console.log(myKey )
}
shyke
la source
J'ai quelque chose comme ça, mais si je rafraîchis la page, elle se bloque complètement
rabiaasif
@rabiaasif parce que les données ne sont plus là, vous devez les conserver ou les stocker dans le stockage local
Drew Cordano
3

Il n'est pas nécessaire d'utiliser withRouter. Cela fonctionne pour moi:

Dans votre page parent,

<BrowserRouter>
   <Switch>
        <Route path="/routeA" render={(props)=> (
          <ComponentA {...props} propDummy={50} />
        )} />

        <Route path="/routeB" render={(props)=> (
          <ComponentB {...props} propWhatever={100} />
          )} /> 
      </Switch>
</BrowserRouter>

Ensuite, dans ComponentA ou ComponentB, vous pouvez accéder

this.props.history

, y compris la méthode this.props.history.push.

joedotnot
la source
Je pense que vous n'en aviez pas besoin withRouterparce que vous avez encapsulé votre composant BrowserRouter, qui fonctionne de la même manière.
Pie 'Oh' Pah
Oui et vous passez le propsbas dans chaque composant qui comprend l' historyhélice.
Jeremy
2

Pour utiliser React 16.8+ (withHooks), vous pouvez utiliser cette méthode

import React from 'react';
import { useHistory } from 'react-router-dom';

export default function SomeFunctionalComponent() {
let history = useHistory(); // should be called inside react component

const handleClickButton = () => {    
"funcionAPICALL"
       .then(response => {
             if (response.status >= 200 && response.status < 300) {
                 history.push('/template');
              });
}

return ( <div> Some component stuff 
    <p>To make API POST request and redirect to "/template" click a button API CALL</p>
    <button onClick={handleClickButton}>API CALL<button>
</div>)
} 

Source ici pour en savoir plus https://reacttraining.com/react-router/web/example/auth-workflow

P Mill
la source
-12

Ajoutez des informations pour obtenir les paramètres de requête.

const queryParams = new URLSearchParams(this.props.location.search);
console.log('assuming query param is id', queryParams.get('id');

Pour plus d'informations sur URLSearchParams, consultez ce lien URLSearchParams

kamal pandey
la source
1
Ce n'est pas du tout pertinent pour React Router 4.
Colby Cox