¿Cuál es la mejor manera de redirigir una página usando React Router?

102

Soy nuevo en React Router y descubro que hay muchas formas de redirigir una página:

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

    import { browserHistory } from 'react-router';
    //do something...
    browserHistory.push("/path");
    
  2. Utilizando 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. En React Router v4, hay this.context.history.push("/path")y this.props.history.push("/path"). Detalles: ¿Cómo pasar al historial en React Router v4?

Estoy tan confundido con todas estas opciones, ¿hay una mejor manera de redirigir una página?

Liutong Chen
fuente
estás usando v4, ¿sí?
azium
1
el enlace a la otra pila que publicó es bastante claro, recomendaría usarwithRouter
azium

Respuestas:

175

En realidad, depende de su caso de uso.

1) Quiere proteger su ruta de usuarios no autorizados

Si ese es el caso, puede usar el componente llamado <Redirect />y puede implementar la siguiente 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>
}

Tenga en cuenta que si desea <Redirect />trabajar de la manera que espera, debe colocarlo dentro del método de renderizado de su componente para que eventualmente se considere como un elemento DOM; de lo contrario, no funcionará.

2) Desea redirigir después de una determinada acción (digamos después de crear un elemento)

En ese caso, puede usar el historial:

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

o

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

Para tener acceso al historial, puede envolver su componente con un HOC llamado withRouter. Cuando envuelve su componente con él, pasa match locationy se historyapoya. Para obtener más detalles, consulte la documentación oficial de withRouter .

Si el componente es un niño de un <Route />componente, es decir, si se trata de algo así <Route path='/path' component={myComponent} />, usted no tiene que ajustar su componente con withRouter, ya que <Route />los pases match, locationy historya su hijo.

3) Redirigir después de hacer clic en algún elemento

Aquí hay dos opciones. Puede usar history.push()pasándolo a un onClickevento:

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

o puede utilizar un <Link />componente:

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

Creo que la regla general con este caso es intentar usar <Link />primero, supongo que especialmente por el rendimiento.

Cagri Yardimci
fuente
Me está funcionando `this.props.history.push (" / ");` React-router - v4.2 Gracias @Cagri
MD Ashik
stackoverflow.com/questions/60579292/… ¿Podrías echar un vistazo a estas preguntas?
a125
En la última opción, debido a que el componente tiene historyen sus accesorios para poder hacer this.props.history.push('/path'), significa que el componente es hijo de <Route/>o tiene withRouterenvoltorio en la exportación ¿correcto?
Andre
Entonces, es posible enrutar a otro componente sin especificar <Route path='/path' component={Comp}/>, supongo que simplemente render() { return <Comp/>}en una condición.
Andre
@Andre, sí, eso es correcto para el uso de, this.props.historysin embargo, no estoy seguro de haber respondido correctamente la segunda pregunta. ¿Qué quieres decir exactamente con route to another component?
Cagri Yardimci
6

Ahora con react-router v15.1y en adelante podemos useHistoryenganchar, esta es una forma súper simple y clara. Aquí hay un ejemplo simple del blog fuente.

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

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

Puede usar esto dentro de cualquier componente funcional y ganchos personalizados. Y sí, esto no funcionará con los componentes de clase al igual que cualquier otro gancho.

Obtenga más información sobre esto aquí https://reacttraining.com/blog/react-router-v5-1/#usehistory

Anand Singh
fuente
3

También puede usar la biblioteca dom del enrutador react 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
fuente
1

Una de las formas más sencillas: use Link de la siguiente manera:

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

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

Si queremos cubrir toda la sección div como enlace:

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

RameshD
fuente
0

También puede Redirecthacerlo de la Routesiguiente manera. Esto es para manejar rutas no válidas.

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