Qual é a melhor maneira de redirecionar uma página usando o React Router?

102

Eu sou novo no React Router e aprendi que existem muitas maneiras de redirecionar uma página:

  1. Usando browserHistory.push("/path")

    import { browserHistory } from 'react-router';
    //do something...
    browserHistory.push("/path");
    
  2. Usando 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. No React Router v4, existe this.context.history.push("/path")e this.props.history.push("/path"). Detalhes: como enviar para o histórico no React Router v4?

Estou tão confuso com todas essas opções. Existe uma melhor maneira de redirecionar uma página?

Liutong Chen
fonte
voce esta usando v4 sim?
azium
1
o link para a outra pilha que você postou é bem claro, eu recomendaria usarwithRouter
azium

Respostas:

174

Na verdade, depende do seu caso de uso.

1) Você deseja proteger sua rota de usuários não autorizados

Se for esse o caso, você pode usar o componente chamado <Redirect />e pode implementar a seguinte lógica:

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

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

Lembre-se de que, se quiser <Redirect />trabalhar da maneira esperada, você deve colocá-lo dentro do método de renderização do seu componente para que seja eventualmente considerado um elemento DOM, caso contrário, não funcionará.

2) Você deseja redirecionar após uma determinada ação (digamos, após criar um item)

Nesse caso, você pode usar o histórico:

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

ou

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

Para ter acesso ao histórico, você pode envolver seu componente com um HOC chamado withRouter. Quando você envolve seu componente com ele, ele passa match locatione historyadere. Para obter mais detalhes, consulte a documentação oficial do withRouter .

Se o componente é um filho de um <Route />componente, ou seja, se é algo como <Route path='/path' component={myComponent} />, você não tem que envolver seu componente com withRouter, porque <Route />passes match, locatione historyao seu filho.

3) Redirecionar após clicar em algum elemento

Existem duas opções aqui. Você pode usá- history.push()lo passando para um onClickevento:

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

ou você pode usar um <Link />componente:

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

Acho que a regra neste caso é tentar usar <Link />primeiro, suponho que especialmente por causa do desempenho.

Cagri Yardimci
fonte
Está funcionando para mim `this.props.history.push (" / ");` React-router - v4.2 Obrigado @Cagri
MD Ashik
stackoverflow.com/questions/60579292/… Você poderia dar uma olhada nestas perguntas?
a125
Na última opção, porque o componente tem historyem seus props poder fazer this.props.history.push('/path'), significa que o componente é filho de <Route/>ou tem withRouterwrapper na exportação correto?
André
Portanto, é possível rotear para outro componente sem especificar <Route path='/path' component={Comp}/>, acho que simplesmente render() { return <Comp/>}em uma condição?
Andre
@Andre sim, isso é correto para o uso de, this.props.historymas não tenho certeza se acertei sua segunda pergunta? O que você quer dizer exatamente com route to another component?
Cagri Yardimci
6

Agora, com o react-router v15.1e em diante, podemos useHistoryligar, Esta é uma forma super simples e clara. Aqui está um exemplo simples do blog de origem.

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

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

Você pode usar isso em qualquer componente funcional e ganchos personalizados. E sim, isso não funcionará com componentes de classe como qualquer outro gancho.

Saiba mais sobre isso aqui https://reacttraining.com/blog/react-router-v5-1/#usehistory

Anand Singh
fonte
3

Você também pode usar a biblioteca 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
fonte
1

Uma das maneiras mais simples: use o Link da seguinte maneira:

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

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

Se quisermos cobrir toda a seção div como link:

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

Você também pode fazer Redirecto Routeseguinte. Isso é para lidar com rotas inválidas.

<Route path='*' render={() => 
     (
       <Redirect to="/error"/>
     )
}/>
Pramuditha
fonte