Si se dirige a entornos de navegador, debe usar el react-router-dom
paquete, en lugar de react-router
. Están siguiendo el mismo enfoque que React, para separar el núcleo, ( react
) y el código específico de la plataforma, ( react-dom
, react-native
) con la sutil diferencia de que no necesita instalar dos paquetes separados, por lo que los paquetes de entorno contienen todo necesitas. Puedes agregarlo a tu proyecto como:
yarn add react-router-dom
o
npm i react-router-dom
Lo primero que debe hacer es proporcionar un <BrowserRouter>
como el componente principal más alto en su aplicación. <BrowserRouter>
usa la history
API HTML5 y la administra por usted, por lo que no tiene que preocuparse por instanciarlo usted mismo y pasarlo al <BrowserRouter>
componente como accesorio (como lo hizo en versiones anteriores).
En V4, para navegar programáticamente, necesita acceder al history
objeto, que está disponible a través de React context
, siempre que tenga un componente de <BrowserRouter>
proveedor como el principal superior en su aplicación. La biblioteca expone a través del contexto el router
objeto, que en sí mismo contiene history
como una propiedad. La history
interfaz ofrece varios métodos de navegación, como push
, replace
y goBack
, entre otros. Puede consultar la lista completa de propiedades y métodos aquí .
Nota importante para los usuarios de Redux / Mobx
Si está utilizando redux o mobx como su biblioteca de administración de estado en su aplicación, es posible que haya encontrado problemas con los componentes que deberían tener en cuenta la ubicación pero que no se vuelven a reproducir después de activar una actualización de URL
Eso sucede porque react-router
pasa location
a los componentes utilizando el modelo de contexto.
Tanto connect como observador crean componentes cuyos métodos shouldComponentUpdate hacen una comparación superficial de sus accesorios actuales y sus próximos accesorios. Esos componentes solo se volverán a renderizar cuando haya cambiado al menos un accesorio. Esto significa que para garantizar que se actualicen cuando cambie la ubicación, deberán recibir un accesorio que cambie cuando cambie la ubicación.
Los 2 enfoques para resolver esto son:
- Envuelva su componente conectado de una manera sin caminos
<Route />
. El location
objeto actual es uno de los accesorios que un <Route>
pasa al componente que representa
- Envuelva su componente conectado con el
withRouter
componente de orden superior, que de hecho tiene el mismo efecto e inyecta location
como accesorio
Dejando eso de lado, hay cuatro formas de navegar programáticamente, ordenadas por recomendación:
1.- Usando un <Route>
componente
Promueve un estilo declarativo. Antes de v4, los
<Route />
componentes se colocaban en la parte superior de la jerarquía de componentes, teniendo que pensar de antemano en la estructura de sus rutas. Sin embargo, ahora puede tener
<Route>
componentes en
cualquier parte de su árbol, lo que le permite tener un control más preciso para la representación condicional dependiendo de la URL.
Route
inyecta
match
,
location
y
history
como accesorios en su componente. Los métodos de navegación (tales como
push
,
replace
,
goBack
...) están disponibles como propiedades del
history
objeto.
Hay 3 formas de renderizar algo con a Route
, usando cualquiera de los dos component
, render
o children
accesorios, pero no use más de uno en el mismo Route
. La elección depende del caso de uso, pero básicamente las dos primeras opciones solo mostrarán su componente si path
coincide con la ubicación de la URL, mientras que con children
el componente se mostrará si la ruta coincide con la ubicación o no (útil para ajustar la interfaz de usuario basada en la URL pareo).
Si desea personalizar la salida de representación de componente , es necesario envolver su componente en una función y utiliza la render
opción, a fin de pasar a su componente cualesquiera otros apoyos que usted desea, además de match
, location
y history
. Un ejemplo para ilustrar:
import { BrowserRouter as Router } from 'react-router-dom'
const ButtonToNavigate = ({ title, history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
{title}
</button>
);
const SomeComponent = () => (
<Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)
const App = () => (
<Router>
<SomeComponent /> // Notice how in v4 we can have any other component interleaved
<AnotherComponent />
</Router>
);
2.- Usando withRouter
HoC
Este componente de orden superior inyectará los mismos accesorios que Route
. Sin embargo, conlleva la limitación de que solo puede tener 1 HoC por archivo.
import { withRouter } from 'react-router-dom'
const ButtonToNavigate = ({ history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
Navigate
</button>
);
ButtonToNavigate.propTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired,
}),
};
export default withRouter(ButtonToNavigate);
3.- Usando un Redirect
componente
La representación de a
<Redirect>
navegará a una nueva ubicación. Pero tenga en cuenta que,
de forma predeterminada , la ubicación actual se reemplaza por la nueva, como las redirecciones del lado del servidor (HTTP 3xx). La nueva ubicación es proporcionada por
to
prop, que puede ser una cadena (URL para redirigir a) o un
location
objeto. Si quieres
insertar una nueva entrada en el historial , pasa también un
push
accesorio y configúralo en
true
<Redirect to="/your-new-location" push />
4.- Accediendo router
manualmente a través del contexto
Un poco desanimado porque el
contexto sigue siendo una API experimental y es probable que se rompa / cambie en futuras versiones de React
const ButtonToNavigate = (props, context) => (
<button
type="button"
onClick={() => context.router.history.push('/my-new-location')}
>
Navigate to a new location
</button>
);
ButtonToNavigate.contextTypes = {
router: React.PropTypes.shape({
history: React.PropTypes.object.isRequired,
}),
};
No hace falta decir que también hay otros componentes del enrutador destinados a ecosistemas que no son del navegador, como el <NativeRouter>
que replica una pila de navegación en la memoria y apunta a la plataforma React Native, disponible a través del react-router-native
paquete.
Para cualquier referencia adicional, no dude en consultar los documentos oficiales . También hay un video hecho por uno de los coautores de la biblioteca que proporciona una introducción bastante buena al react-router v4, destacando algunos de los principales cambios.