Jaki jest najlepszy sposób na przekierowanie strony za pomocą React Router?

110

Jestem nowy w React Router i dowiedziałem się, że istnieje wiele sposobów przekierowania strony:

  1. Za pomocą browserHistory.push("/path")

    import { browserHistory } from 'react-router';
    //do something...
    browserHistory.push("/path");
    
  2. Za pomocą 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. W React Router v4 jest this.context.history.push("/path")i this.props.history.push("/path"). Szczegóły: Jak przejść do historii w React Router v4?

Jestem tak zdezorientowany tymi wszystkimi opcjami, czy istnieje najlepszy sposób na przekierowanie strony?

Liutong Chen
źródło
używasz v4 tak?
azium
1
link do innego stosu, który opublikowałeś, jest całkiem jasny, polecam użyciewithRouter
azium

Odpowiedzi:

187

Właściwie to zależy od twojego przypadku użycia.

1) Chcesz chronić swoją trasę przed nieautoryzowanymi użytkownikami

W takim przypadku można użyć wywoływanego komponentu <Redirect />i zaimplementować następującą logikę:

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

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

Pamiętaj, że jeśli chcesz <Redirect />działać zgodnie z oczekiwaniami, powinieneś umieścić go wewnątrz metody renderowania swojego komponentu, aby ostatecznie został uznany za element DOM, w przeciwnym razie nie zadziała.

2) Chcesz przekierować po wykonaniu określonej czynności (powiedzmy po utworzeniu elementu)

W takim przypadku możesz skorzystać z historii:

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

lub

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

Aby mieć dostęp do historii, możesz opakować swój komponent w HOC o nazwie withRouter. Kiedy otoczysz nim swój komponent, przechodzi match locationi historypodpowiada. Aby uzyskać więcej informacji, zapoznaj się z oficjalną dokumentacją withRouter .

Jeśli urządzenie jest dzieckiem <Route />elementu, czyli czy jest coś takiego <Route path='/path' component={myComponent} />, że nie trzeba owinąć składnik z withRouter, ponieważ <Route />podań match, locationi historyjej dziecka.

3) Przekieruj po kliknięciu elementu

Istnieją dwie opcje. Możesz użyć history.push(), przekazując go do onClickwydarzenia:

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

lub możesz użyć <Link />komponentu:

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

Myślę, że praktyczną zasadą w tym przypadku jest próba użycia w <Link />pierwszej kolejności, myślę, że szczególnie ze względu na wydajność.

Cagri Yardimci
źródło
U mnie działa `this.props.history.push (" / ");` React-router - v4.2 Dzięki @Cagri
MD Ashik
stackoverflow.com/questions/60579292/… Czy mógłbyś rzucić okiem na te pytania?
a125
W ostatniej opcji, skoro komponent ma historyw swoich propsach możliwość wykonania this.props.history.push('/path'), to znaczy, że komponent jest dzieckiem <Route/>lub ma withRouteropakowanie w eksporcie, prawda?
Andre
Więc jest możliwe, aby skierować do innego komponentu bez określania <Route path='/path' component={Comp}/>, myślę, że po prostu render() { return <Comp/>}w stanie?
Andre
@Andre tak, to jest poprawne do użytku, this.props.historyale nie jestem pewien, czy twoje drugie pytanie jest poprawne? Co dokładnie masz na myśli route to another component?
Cagri Yardimci
8

Teraz za pomocą routera reaktywnego v15.1i dalej możemy useHistorypodłączyć, To jest super prosty i przejrzysty sposób. Oto prosty przykład z bloga źródłowego.

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

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

Możesz tego użyć w dowolnym funkcjonalnym komponencie i niestandardowych zaczepach. I tak, to nie zadziała z komponentami klasy tak samo jak każdy inny hak.

Dowiedz się więcej na ten temat tutaj https://reacttraining.com/blog/react-router-v5-1/#usehistory

Anand Singh
źródło
3

Możesz także skorzystać z biblioteki React router dom. UseHistory;

`
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
źródło
1

Jeden z najprostszych sposobów: użyj linku w następujący sposób:

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

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

Jeśli chcemy objąć całą sekcję div jako link:

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

RameshD
źródło
0

Możesz również Redirectw Routenastępujący sposób. To służy do obsługi nieprawidłowych tras.

<Route path='*' render={() => 
     (
       <Redirect to="/error"/>
     )
}/>
Pramuditha
źródło