¿Cómo pasar parámetros con history.push / Link / Redirect en react-router v4?

218

¿Cómo podemos pasar el parámetro con this.props.history.push('/page')React-Router v4?

.then(response => {
       var r = this;
        if (response.status >= 200 && response.status < 300) {
             r.props.history.push('/template');
          });
IshanGarg
fuente
El componente que se representa por una Routedebe tener acceso a this.props.location, this.props.history, etc. Creo que no es necesario utilizar refmás con v4. Intenta hacerlothis.props.history.push('/template');
saadq
No es ref, es variable que apunta a esto; this.props.history.push ('/ template'); llévame a la página siguiente pero quiero pasarles accesorios con ellos .ref = this;
IshanGarg
¿Estás intentando pasar propsal componente que coincide con la ruta? Creo que este hilo de GitHub aborda su preocupación.
saadq
JFYI: eliminé <a href> y agregué <Link>, que también tiene la opción de enviar el estado, al que se puede acceder en la página siguiente a través de this.props.location.state.
Manohar Reddy Poreddy
¿Podría marcar una de las respuestas como 'respuesta'? Estoy seguro de que las personas que pasan el tiempo escribiéndolas lo apreciarán.
James Poulose

Respuestas:

392

En primer lugar, no necesita hacer var r = this;esto enif statement refiere al contexto de la devolución de llamada en sí, que como está utilizando la función de flecha se refiere al contexto del componente Reaccionar.

Según los documentos:

Los objetos de historial suelen tener las siguientes propiedades y métodos:

  • longitud - (número) El número de entradas en la pila de historial
  • action - (string) La acción actual (PUSH, REPLACE o POP)
  • ubicación - (objeto) La ubicación actual. Puede tener las siguientes propiedades:

    • ruta - (cadena) La ruta de la URL
    • buscar - (cadena) La cadena de consulta de URL
    • hash - (cadena) El fragmento de hash de URL
    • state: estado específico de la ubicación (cadena) que se proporcionó, por ejemplo, a push (ruta, estado) cuando esta ubicación se introdujo en la pila. Solo disponible en el navegador y el historial de memoria.
  • push (ruta, [estado]) - (función) Inserta una nueva entrada en la pila de historial
  • replace (ruta, [estado]) - (función) Reemplaza la entrada actual en la pila del historial
  • go (n) - (función) Mueve el puntero en la pila del historial por n entradas
  • goBack () - (función) Equivalente a ir (-1)
  • goForward () - (función) Equivalente a ir (1)
  • bloque (indicador) - (función) Evita la navegación

Entonces, mientras navegas, puedes pasar accesorios al objeto de historia como

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

o de manera similar para el Linkcomponente o el Redirectcomponente

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

y luego en el componente que se representa con la /templateruta, puede acceder a los accesorios pasados ​​como

this.props.location.state.detail

También tenga en cuenta que, al usar el historial o los objetos de ubicación de accesorios, debe conectar el componente withRouter.

Según los documentos:

withRouter

Puede obtener acceso a las propiedades del objeto de historial y la <Route>'scoincidencia más cercana a través del withRoutercomponente de orden superior. withRouter volverá a renderizar su componente cada vez que la ruta cambie con los mismos accesorios que <Route>render props: { match, location, history }.

Shubham Khatri
fuente
3
sí, eso funcionó ¡Gracias! Pero no estoy seguro de por qué this.props.history.push('/template',response.data)no funciona. Según los documentos de push(path, [state]), ¿no crees que debería funcionar?
Sanket Patel el
1
¡Gracias por esto! En mi caso, solo estaba pasando la historia directamente, por lo que accedí a mi utilería a través de this.props.history.location.state.propName -
Nunchucks
@SanketPatel necesita hacer esto this.props.history.push ('/ template', {response: response.data})
Arsalan Ahmed Quershi
¿Es posible abrir la ruta en una nueva pestaña mientras se pasan datos en la variable de estado cuando se navega, puede pasar accesorios al objeto de historial?
Gaurav Kumar
3
¿Qué pasa con goBack ()? cuando navego hacia atrás con goBack (), no puedo ver ninguno de los estados históricos en props.location o props.history.location. Navegar hacia adelante con push () funciona bien
MariusB
40

puedes usar,

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

entonces puede acceder a los datos analizados desde el /templatecomponente siguiendo el código,

const state = this.props.location.state

Leer más sobre React Session History Management

Tenusha Guruge
fuente
Esta lógica funcionó para mí mientras history.push con back_url en estado this.props.history.push (redirect_url, {back_url: '/ Need_url'}); y obtener esto en la página de destino por this.props.location.state.back_url
Braham Dev Yadav
25
  • Para las versiones anteriores :

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

    Y obtenga los datos en el componente relacionado al igual que a continuación:

    this.props.location.state // it is equal to yourData
  • Para las versiones más nuevas , la forma anterior funciona bien, pero hay una nueva forma:

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

    Y obtenga los datos en el componente relacionado al igual que a continuación:

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

Sugerencia : el statenombre de la clave se usó en las versiones anteriores y para las versiones más nuevas, puede usar su nombre personalizado para pasar datos y usar el statenombre no es esencial.

AmerllicA
fuente
comparte la referencia, que dice que el estado no es esencial, si lo tienes a mano
Akshay Vijay Jain
Estimado @AkshayVijayJain, es mi experiencia de codificación. No escribí esa oración basada en un documento o referencia.
AmerllicA
22

Extender la solución (sugerida por Shubham Khatri) para usar con ganchos React (16.8 en adelante):

package.json (always worth updating to latest packages)

{
     ...

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

     ...
}

Pasando parámetros con historial de empuje:

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;

Accediendo al parámetro pasado usando useLocation desde '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
fuente
¡Muchas gracias, no pude encontrar una alternativa actualizada excepto su respuesta!
jamezrin
10

Si necesita pasar parámetros de URL

hay una gran explicación de publicación de Tyler McGinnis en su sitio, Enlace a la publicación

Aquí hay ejemplos de código:

  1. en el componente history.push:

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

  2. en el componente del enrutador define la ruta:

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

  3. en el componente de inicio:

componentDidMount(){
    const { myKey } = this.props.match.params
    console.log(myKey )
}
tímido
fuente
Tengo algo como esto, pero si actualizo la página se bloquea por completo
rabiaasif
@rabiaasif debido a que los datos ya no están allí, debe conservarlos o almacenarlos en el almacenamiento local
Drew Cordano
3

No es necesario usar con Router. Esto funciona para mi:

En tu página principal,

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

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

Luego, en Componente A o Componente B puede acceder

this.props.history

objeto, incluido el método this.props.history.push.

joedotnot
fuente
Creo que no lo necesitabas withRouterporque envolviste tu componente BrowserRouter, que funciona igual.
Pie 'Oh' Pah
Sí, y está pasando el contenido propsa cada componente que incluye el historyaccesorio.
Jeremy
2

Para usar React 16.8+ (con ganchos) puede usar de esta manera

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

Fuente aquí para leer más https://reacttraining.com/react-router/web/example/auth-workflow

P Mill
fuente
-12

Agregue información para obtener parámetros de consulta.

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

Para obtener más información sobre URLSearchParams, consulte este enlace URLSearchParams

kamal pandey
fuente
1
Esto no es relevante para React Router 4.
Colby Cox