Como passar parâmetros com history.push / Link / Redirect no react-router v4?


216

Como podemos passar parâmetros this.props.history.push('/page')no React-Router v4?

.then(response => {
       var r = this;
        if (response.status >= 200 && response.status < 300) {
             r.props.history.push('/template');
          });

O componente que é processado por um Routedeve ter acesso a this.props.location, this.props.history, etc. Eu acho que você não precisa usar refmais com v4. Tente fazerthis.props.history.push('/template');
— saadq 22/17/17

Não é ref, é variável que aponta para isso; this.props.history.push ('/ template'); leve-me para a próxima página, mas eu quero passar adereços com eles .ref = this;
— IshanGarg

Você está tentando passar propspara o componente que corresponde à rota? Eu acho que esse segmento do GitHub soluciona sua preocupação.
— Saadq 23/05

JFYI - Eu removi <a href> e adicionei <Link>, que também tem a opção de enviar estado, que pode ser acessado na próxima página via this.props.location.state.
— Manohar Reddy Poreddy 21/11/19

Você poderia marcar uma das respostas como 'resposta'. Estou certo de que as pessoas que passam o tempo digitando-as irão gostar.
— James Poulose 25/03

Respostas:


391

Primeiro de tudo, você não precisa fazer var r = this;isso emif statement se refere ao contexto do retorno de chamada em si, pois, como você está usando a função de seta, refere-se ao contexto do componente React.

De acordo com os documentos:

objetos de histórico geralmente têm as seguintes propriedades e métodos:

  • length - (number) O número de entradas na pilha do histórico
  • action - (string) A ação atual (PUSH, REPLACE ou POP)
  • local - (objeto) O local atual. Pode ter as seguintes propriedades:

    • nome do caminho - (string) O caminho do URL
    • search - (string) A string de consulta do URL
    • hash - (string) O fragmento de hash da URL
    • state - (string) estado específico do local que foi fornecido para, por exemplo, enviar (caminho, estado) quando esse local foi enviado para a pilha. Disponível apenas no histórico do navegador e da memória.
  • push (caminho, [estado]) - (função) Coloca uma nova entrada na pilha de histórico
  • substituir (caminho, [estado]) - (função) Substitui a entrada atual na pilha do histórico
  • go (n) - (função) Move o ponteiro na pilha do histórico por n entradas
  • goBack () - (função) Equivalente a go (-1)
  • goForward () - (função) Equivalente a go (1)
  • bloco (prompt) - (função) Impede a navegação

Portanto, durante a navegação, você pode passar adereços para o objeto histórico, como

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

ou similarmente para o Linkcomponente ou o Redirectcomponente

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

e, em seguida, no componente que é renderizado com a /templaterota, você pode acessar os adereços passados ​​como

this.props.location.state.detail

Lembre-se também de que, ao usar objetos de histórico ou localização de objetos, você precisa conectar o componente withRouter.

De acordo com os documentos:

withRouter

Você pode obter acesso às propriedades do objeto histórico e a <Route>'scorrespondência mais próxima por meio do withRoutercomponente de ordem superior. withRouter renderizará novamente seu componente toda vez que a rota for alterada com os mesmos acessórios que a <Route>renderização props: { match, location, history }.


3
sim, isso funcionou. Mas não sei por que this.props.history.push('/template',response.data)não está trabalhando. De acordo com a documentação de push(path, [state]), você não acha que deve funcionar?
— Sanket Patel

1
Obrigado por isso! No meu caso eu só estava passando história diretamente, então eu acessada meu prop via this.props.history.location.state.propName -
— Nunchucks

@SanketPatel, você precisa fazer isso this.props.history.push ('/ template', {response: response.data})
— Arsalan Ahmed Quershi

É possível abrir a rota em uma nova guia enquanto passa dados na variável de estado ao navegar, você pode passar adereços para o objeto de histórico?
— Gaurav Kumar

3
e quanto a goBack ()? ao navegar de volta com goBack (), não consigo ver nenhum dos estados do histórico em props.location ou props.history.location. Navegando para frente com push () funciona bem
— MariusB

40

você pode usar,

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

então você pode acessar os dados analisados ​​do /templatecomponente seguindo o código,

const state = this.props.location.state

Leia mais sobre o React Session History Management


Essa lógica funcionou para mim enquanto history.push com back_url no estado this.props.history.push (redirect_url, {back_url: '/ needs_url'}); e obtê-lo na página de destino por this.props.location.state.back_url
— Braham Dev Yadav

24
  • Para as versões anteriores :

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

    E obtenha os dados no componente relacionado, como abaixo:

    this.props.location.state // it is equal to yourData
  • Para as versões mais recentes, a maneira acima funciona bem, mas existe uma nova maneira:

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

    E obtenha os dados no componente relacionado, como abaixo:

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

Dica : o statenome da chave foi usado nas versões anteriores e, para versões mais recentes, você pode usar seu nome personalizado para transmitir dados e o uso do statenome não é essencial.


compartilhe a referência, que diz que o estado não é essencial, se você o tiver útil
— Akshay Vijay Jain

Caro @AkshayVijayJain, é a minha experiência de codificação. Não escrevi essa frase com base em um documento ou referência.
— AmerllicA

19

Estendendo a solução (sugerida por Shubham Khatri) para uso com ganchos React (16,8 em diante):

package.json (always worth updating to latest packages)

{
     ...

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

     ...
}

Passando parâmetros com histórico de envio:

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;

Acessando o parâmetro passado usando useLocation 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]);

};

Muito obrigado, não foi possível encontrar uma alternativa atualizada, exceto a sua resposta!
— jamezrin 24/04

10

Se você precisar passar parâmetros de URL

há uma ótima explicação de Tyler McGinnis em seu site, Link para o post

Aqui estão alguns exemplos de código:

  1. no componente history.push:

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

  2. no componente do roteador, você define a rota:

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

  3. no componente Home:

componentDidMount(){
    const { myKey } = this.props.match.params
    console.log(myKey )
}

Eu tenho algo parecido com isto, mas se eu atualizar a página ela trava completamente
— rabiaasif

@rabiaasif porque os dados não estão mais lá, você precisa persistir ou armazená-los no armazenamento local
— Drew Cordano

3

Não é necessário usar withRouter. Isso funciona para mim:

Na sua página pai,

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

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

Em seguida, no ComponentA ou no ComponentB, você pode acessar

this.props.history

objeto, incluindo o método this.props.history.push.


Acho que você não precisou withRouterporque envolveu seu componente BrowserRouter, que funciona da mesma forma.
— Pie 'Oh' Pah

Sim e você está passando o propsconteúdo para cada componente que inclui o historysuporte.
— Jeremy

2

Para usar o React 16.8+ (withHooks), você pode usar desta maneira

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

Fonte aqui para ler mais https://reacttraining.com/react-router/web/example/auth-workflow


-12

Adicione informações para obter parâmetros de consulta.

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

Para mais informações sobre URLSearchParams, verifique este link URLSearchParams


1
Isso não é de todo relevante para reagir Router 4.
— Colby Cox
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.