Acabo de reemplazar react-routerde v3 a v4.
Pero no estoy seguro de cómo navegar mediante programación en la función miembro de a Component. es decir, en la handleClick()función que quiero navegar /path/some/wheredespués de procesar algunos datos. Solía hacer eso por:
import { browserHistory } from 'react-router'
browserHistory.push('/path/some/where')
Pero no puedo encontrar tales interfaces en v4.
¿Cómo puedo navegar usando v4?
reactjs
ecmascript-6
react-router-v4
Colin Witkamp
fuente
fuente

Component? Por ejemplo, dentro de las acciones redux.Respuestas:
Si se dirige a entornos de navegador, debe usar el
react-router-dompaquete, en lugar dereact-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-domo
npm i react-router-domLo primero que debe hacer es proporcionar un
<BrowserRouter>como el componente principal más alto en su aplicación.<BrowserRouter>usa lahistoryAPI 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
historyobjeto, que está disponible a través de Reactcontext, siempre que tenga un componente de<BrowserRouter>proveedor como el principal superior en su aplicación. La biblioteca expone a través del contexto elrouterobjeto, que en sí mismo contienehistorycomo una propiedad. Lahistoryinterfaz ofrece varios métodos de navegación, comopush,replaceygoBack, 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 URLEso sucede porque
react-routerpasalocationa los componentes utilizando el modelo de contexto.Los 2 enfoques para resolver esto son:
<Route />. Ellocationobjeto actual es uno de los accesorios que un<Route>pasa al componente que representawithRoutercomponente de orden superior, que de hecho tiene el mismo efecto e inyectalocationcomo accesorioDejando eso de lado, hay cuatro formas de navegar programáticamente, ordenadas por recomendación:
1.- Usando un
Promueve un estilo declarativo. Antes de v4, los<Route>componente<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.Routeinyectamatch,locationyhistorycomo accesorios en su componente. Los métodos de navegación (tales comopush,replace,goBack...) están disponibles como propiedades delhistoryobjeto.Hay 3 formas de renderizar algo con a
Route, usando cualquiera de los doscomponent,renderochildrenaccesorios, pero no use más de uno en el mismoRoute. La elección depende del caso de uso, pero básicamente las dos primeras opciones solo mostrarán su componente sipathcoincide con la ubicación de la URL, mientras que conchildrenel 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
renderopción, a fin de pasar a su componente cualesquiera otros apoyos que usted desea, además dematch,locationyhistory. Un ejemplo para ilustrar:2.- Usando
withRouterHoCEste 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.3.- Usando un
La representación de aRedirectcomponente<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 portoprop, que puede ser una cadena (URL para redirigir a) o unlocationobjeto. Si quieres insertar una nueva entrada en el historial , pasa también unpushaccesorio y configúralo entrue4.- Accediendo
Un poco desanimado porque el contexto sigue siendo una API experimental y es probable que se rompa / cambie en futuras versiones de Reactroutermanualmente a través del contextoNo 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 delreact-router-nativepaquete.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.
fuente
withRouterdereact-router-domwithRouterdereact-router-dom. El history.push cambia la url, pero no parece cargar<Route>hasta que<Router>dentro un componente React con el que está decorado@observer, lo que desencadena este problema . La solución es tener@withRouteren cada componente de React.withRouteres simplemente un HOC que utiliza unRoutebajo el capó. Lo que significa que solo usa 3 accesorios, historia, partido y ubicación . En el ejemplo anterior, parece quepushes un accesorio quewithRouterse agregaríaButtonToNavigate, pero ese no es el caso.props.history.pushtendría que ser utilizado en su lugar. Espero que esto ayude a otros que estaban un poco confundidos.browserHistory.push('/path/some/where')simplemente parece mucho más simple. Los autores están tratando de desalentar la programación imperativa, ¡pero a veces simplemente funciona mejor!La forma más fácil de hacerlo:
this.props.history.push("/new/url")Nota:
historypropdel componente primario al componente en el que desea invocar la acción si no está disponible.fuente
this.props.historydisponible en su componente, puedeimport {withRouter} from 'react-router-dom'y luegoexport default withRouter(MyComponent)(oconst MyComponent = withRouter(...)) e insertará elhistoryelemento en los accesorios de su componente.history.pushy simplemente activar la actualización como cuando hacemos clic en<Link>Tuve un problema similar al migrar a React-Router v4, así que intentaré explicar mi solución a continuación.
No considere esta respuesta como la forma correcta de resolver el problema, imagino que hay una buena posibilidad de que surja algo mejor a medida que React Router v4 se vuelva más maduro y deje beta (incluso puede existir y simplemente no lo descubrí) .
Por contexto, tuve este problema porque ocasionalmente uso
Redux-Sagapara cambiar programáticamente el objeto de historial (por ejemplo, cuando un usuario se autentica con éxito).En los documentos de React Router, eche un vistazo al
<Router>componente y verá que tiene la capacidad de pasar su propio objeto de historia a través de un accesorio. Esta es la esencia de la solución - que la oferta del objeto historia aReact-Routerpartir de un mundial módulo.Pasos:
yarn add historyonpm install history --savecrear un archivo llamado
history.jsen suApp.jscarpeta de nivel (esta era mi preferencia)Agregue este objeto de historial a su componente de enrutador de esta manera
Ajuste la URL como antes importando su objeto de historial global:
Todo debería estar sincronizado ahora, y también tiene acceso a una forma de configurar el objeto de historial mediante programación y no a través de un componente / contenedor.
fuente
Routecomponente.TL; DR:
La respuesta simple y declarativa es que debe usar
<Redirect to={URL} push={boolean} />en combinación consetState()Ejemplo completo aquí . Lee más aquí .
PD. El ejemplo utiliza los inicializadores de propiedades ES7 + para inicializar el estado. Mira aquí también, si estás interesado.
fuente
history.push()métodos.Use
useHistoryhook si está usando componentes de funciónPuede usar
useHistoryhook para obtenerhistoryinstancia.El
useHistorygancho le da acceso a la instancia de historial que puede usar para navegar.Usar
historypropiedad dentro de los componentes de la páginaReact Router inyecta algunas propiedades, incluidos los
historycomponentes de la página.Envuelva los componentes secundarios
withRouterpara inyectar las propiedades del enrutadorwithRouterwrapper inyecta las propiedades del enrutador a los componentes. Por ejemplo, puede usar este contenedor para inyectar el enrutador para cerrar el componente del botón ubicado dentro del menú del usuario.fuente
También puede simplemente usar accesorios para acceder al objeto de historial:
this.props.history.push('new_url')fuente
this.props.historydisponible en su componente, puedeimport {withRouter} from 'react-router-dom'y luegoexport default withRouter(MyComponent)(oconst MyComponent = withRouter(...)) e insertará elhistoryelemento en los accesorios de su componente.Paso 1: solo hay una cosa para importar:
Paso 2: en tu ruta, pasa el historial:
Paso 3: el historial se acepta como parte de los accesorios en el siguiente Componente, por lo que puede simplemente:
Eso fue fácil y realmente poderoso.
fuente
Esto funciona:
fuente
Mi respuesta es similar a la de Alex . No estoy seguro de por qué React-Router hizo esto tan innecesariamente complicado. ¿Por qué debería tener que envolver mi componente con un HoC solo para obtener acceso a lo que es esencialmente global?
De todos modos, si echas un vistazo a cómo se implementaron
<BrowserRouter>, es solo una pequeña envoltura alrededor de la historia .Podemos extraer ese historial para poder importarlo desde cualquier lugar. Sin embargo, el truco es que si está haciendo renderizado del lado del servidor e intenta con
importel módulo de historial, no funcionará porque usa API solo para el navegador. Pero eso está bien porque generalmente solo redirigimos en respuesta a un clic o algún otro evento del lado del cliente. Por lo tanto, probablemente esté bien simularlo:Con la ayuda de webpack, podemos definir algunos variables para saber en qué entorno estamos:
Y ahora puedes
De donde sea. Simplemente devolverá un módulo vacío en el servidor.
Si no desea utilizar estos vars mágicos, solo tendrá que hacerlo
requireen el objeto global donde sea necesario (dentro de su controlador de eventos).importno funcionará porque solo funciona en el nivel superior.fuente
Creo que @rgommezz cubre la mayoría de los casos menos uno que creo que es bastante importante.
Esto me permite escribir un servicio simple con acciones / llamadas a las que puedo llamar para hacer la navegación desde cualquier componente que desee sin hacer mucho HoC en mis componentes ...
No está claro por qué nadie ha proporcionado esta solución antes. Espero que ayude, y si ve algún problema con esto, hágamelo saber.
fuente
He estado probando v4 durante unos días y ... ¡hasta ahora me encanta! Simplemente tiene sentido después de un tiempo.
También tenía la misma pregunta y encontré que manejarlo como el siguiente funcionó mejor (y podría ser incluso cómo se pretende). Utiliza estado, un operador ternario y
<Redirect>.En el constructor ()
En el render ()
En el clickhandler ()
Espero eso ayude. Házmelo saber.
fuente
Luché con esto por un tiempo, algo tan simple, pero tan complicado, porque ReactJS es una forma completamente diferente de escribir aplicaciones web, ¡es muy extraño para nosotros, las personas mayores!
Creé un componente separado para abstraer el desastre:
Luego agréguelo a su
render()método:fuente
Como no hay otra forma de lidiar con este diseño horrible, escribí un componente genérico que utiliza el enfoque
withRouterHOC . El siguiente ejemplo es envolver unbuttonelemento, pero puede cambiar a cualquier elemento en el que pueda hacer clic:Uso:
fuente
Si no ha encontrado this.props.history disponible en su componente, intente esto
fuente
Como a veces prefiero cambiar las rutas por aplicación y luego por botones, este es un ejemplo de trabajo mínimo que funciona para mí:
fuente
Para aquellos de ustedes que requieren redirigir antes de iniciar completamente un enrutador usando
React RouteroReact Router Dompuede proporcionar una redirección simplemente accediendo al objeto de historial y presionando un nuevo estado dentro de su construcciónapp.js. Considera lo siguiente:Aquí queremos cambiar las Rutas de salida que dependen de un subdominio, al interactuar con el objeto de historial antes de que el componente se procese, podemos redirigir efectivamente sin dejar nuestras rutas intactas.
fuente