Jak przekazać parametry za pomocą history.push / Link / Redirect w React-Router v4?

217

Jak możemy przekazać parametr this.props.history.push('/page')w React-Router v4?

.then(response => {
       var r = this;
        if (response.status >= 200 && response.status < 300) {
             r.props.history.push('/template');
          });
IshanGarg
źródło
Składnik, który jest renderowany przez Routepowinni mieć dostęp do this.props.location, this.props.historyitp Myślę, że nie trzeba używać refjuż z v4. Spróbuj zrobićthis.props.history.push('/template');
saadq
To nie jest ref, zmienna wskazuje na to; this.props.history.push ('/ template'); zabierz mnie do następnej strony, ale chcę przekazać im rekwizyty .ref = this;
IshanGarg
Próbujesz przekazać propskomponent pasujący do trasy? Myślę, że ten wątek GitHub rozwiązuje problem.
saadq
JFYI - usunąłem <a href> i dodałem <Link>, który ma również opcję wysyłania stanu, do którego można uzyskać dostęp na następnej stronie, this.props.location.state.
Manohar Reddy Poreddy
Czy możesz zaznaczyć jedną z odpowiedzi jako „odpowiedź”. Jestem pewien, że ludzie, którzy spędzają czas na ich pisaniu, docenią to.
James Poulose

Odpowiedzi:

391

Przede wszystkim nie musisz tego robić, var r = this;ponieważ if statementodnosi się to do kontekstu samego wywołania zwrotnego, które ponieważ używasz funkcji strzałki, odnosi się do kontekstu komponentu React.

Według dokumentów:

obiekty historyczne mają zazwyczaj następujące właściwości i metody:

  • długość - (liczba) Liczba wpisów w stosie historii
  • action - (string) Bieżąca akcja (PUSH, REPLACE lub POP)
  • lokalizacja - (obiekt) Bieżąca lokalizacja. Może mieć następujące właściwości:

    • ścieżka nazwa - (ciąg) Ścieżka adresu URL
    • szukaj - (ciąg) Ciąg zapytania adresu URL
    • hash - (string) Fragment skrótu adresu URL
    • state - (string) stan specyficzny dla lokalizacji, który został podany np. w celu wypychania (ścieżka, stan), gdy ta lokalizacja została wypchnięta na stos. Dostępne tylko w historii przeglądarki i pamięci.
  • push (ścieżka, [stan]) - (funkcja) Pcha nowy wpis na stos historii
  • replace (ścieżka, [stan]) - (funkcja) Zastępuje bieżący wpis na stosie historii
  • go (n) - (funkcja) Przesuwa wskaźnik na stosie historii o n pozycji
  • goBack () - (funkcja) Odpowiednik go (-1)
  • goForward () - (funkcja) Odpowiednik go (1)
  • blok (monit) - (funkcja) Uniemożliwia nawigację

Podczas nawigacji możesz przekazywać rekwizyty do obiektu historii, takiego jak

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

lub podobnie dla Linkkomponentu lub Redirectkomponentu

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

a następnie w komponencie renderowanym z /templatetrasą, możesz uzyskać dostęp do przekazanych rekwizytów jak

this.props.location.state.detail

Należy również pamiętać, że podczas korzystania z obiektów historii lub lokalizacji z rekwizytów należy połączyć komponent withRouter.

Zgodnie z Dokumentami:

withRouter

Możesz uzyskać dostęp do właściwości obiektu historii i najbliższego <Route>'sdopasowania za pomocą withRouterkomponentu wyższego rzędu. withRouter ponownie renderuje swój komponent za każdym razem, gdy trasa zmienia się z tymi samymi rekwizytami, co <Route>render props: { match, location, history }.

Shubham Khatri
źródło
3
tak, zadziałało. dzięki! Ale nie jestem pewien, dlaczego this.props.history.push('/template',response.data)nie działa. Według dokumentów push(path, [state]), czy nie uważasz, że to powinno działać?
Sanket Patel,
1
Dzięki za to! W moim przypadku przeszedłem tylko historię bezpośrednio, więc uzyskałem dostęp do mojego rekwizytu poprzez this.props.history.location.state.propName -
Nunchucks
@SanketPatel musisz to zrobić this.props.history.push ('/ template', {response: response.data})
Arsalan Ahmed Quershi
Czy możliwe jest otwarcie trasy w nowej karcie podczas przekazywania danych w zmiennej stanu podczas nawigacji można przekazać rekwizyty do obiektu historii?
Gaurav Kumar
3
co z goBack ()? podczas nawigowania wstecz za pomocą goBack () nie widzę żadnego ze stanów historii ani w props.location, ani w props.history.location. Nawigacja do przodu za pomocą push () działa dobrze
MariusB
40

możesz użyć,

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

możesz uzyskać dostęp do przeanalizowanych danych z /templatekomponentu, wykonując następujący kod,

const state = this.props.location.state

Przeczytaj więcej o zarządzaniu historią sesji React

Tenusha Guruge
źródło
Ta logika działała dla mnie, gdy history.push z back_url w stanie this.props.history.push (redirect_url, {back_url: '/ need_url'}); i zdobycie go na stronie docelowej autor: this.props.location.state.back_url
Braham Dev Yadav
24
  • W przypadku wcześniejszych wersji:

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

    I uzyskaj dane w powiązanym komponencie, tak jak poniżej:

    this.props.location.state // it is equal to yourData
  • W przypadku nowszych wersji powyższy sposób działa dobrze, ale istnieje nowy sposób:

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

    I uzyskaj dane w powiązanym komponencie, tak jak poniżej:

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

Wskazówka : statenazwa klucza była używana we wcześniejszych wersjach, aw nowszych wersjach możesz używać swojej niestandardowej nazwy do przekazywania danych, a używanie statenazwy nie jest konieczne.

AmerllicA
źródło
podziel się referencją, która mówi, że stan nie jest niezbędny, jeśli masz go pod ręką
Akshay Vijay Jain
Drogi @AkshayVijayJain, to moje doświadczenie kodowania. Nie napisałem tego zdania na podstawie dokumentu lub referencji.
AmerllicA
21

Rozszerzanie rozwiązania (sugerowanego przez Shubhama Khatri) do użycia z hakami React (od 16.8):

package.json (always worth updating to latest packages)

{
     ...

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

     ...
}

Przekazywanie parametrów z wypychaniem historii:

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;

Dostęp do przekazanego parametru za pomocą useLocation z '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
źródło
Dziękuję bardzo, nie mogłem znaleźć zaktualizowanej alternatywy oprócz twojej odpowiedzi!
jamezrin
10

Jeśli musisz przekazać parametry adresu URL

tam jest świetne wyjaśnienie postu Tyler McGinnis na jego stronie, Link do postu

oto przykłady kodu:

  1. w komponencie history.push:

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

  2. w komponencie routera określasz trasę:

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

  3. w komponencie Home:

componentDidMount(){
    const { myKey } = this.props.match.params
    console.log(myKey )
}
Shyke
źródło
Mam coś takiego, ale jeśli
odświeżę
@rabiaasif, ponieważ danych już nie ma, musisz je
zachować
3

Korzystanie z routera nie jest konieczne. To działa dla mnie:

Na stronie nadrzędnej

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

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

Następnie w ComponentA lub ComponentB można uzyskać dostęp

this.props.history

obiekt, w tym metodę this.props.history.push.

joedotnot
źródło
Myślę, że nie było to konieczne, withRouterponieważ owinąłeś swój komponent BrowserRouter, który działa tak samo.
Pie 'Oh' Pah
Tak i przekazujesz w propsdół do każdego elementu, który obejmuje historyrekwizyt.
Jeremy
2

Aby użyć React 16.8+ (withHooks) , możesz użyć tego sposobu

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

Źródło tutaj, aby przeczytać więcej https://reacttraining.com/react-router/web/example/auth-workflow

P Mill
źródło
-12

Dodaj informacje, aby uzyskać parametry zapytania.

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

Aby uzyskać więcej informacji o URLSearchParams, sprawdź ten link URLSearchParams

kamal pandey
źródło
1
Nie dotyczy to w ogóle React Router 4.
Colby Cox