Con react-router
puedo usar el Link
elemento para crear enlaces que son manejados de forma nativa por react router.
Veo internamente que llama this.context.transitionTo(...)
.
Quiero hacer una navegación No desde un enlace, sino desde una selección desplegable (como ejemplo). ¿Cómo puedo hacer esto en código? ¿Qué es this.context
?
Vi el Navigation
mixin, pero ¿puedo hacer esto sin mixins
?
reactjs
react-router
George Mauer
fuente
fuente
Respuestas:
Hay un nuevo
useHistory
gancho en React Router> 5.1.0 si está utilizando React> 16.8.0 y componentes funcionales.Con v4 de React Router, hay tres enfoques que puede adoptar para el enrutamiento programático dentro de los componentes.
withRouter
componente de orden superior.<Route>
context
.React Router es principalmente un contenedor alrededor de la
history
biblioteca.history
maneja la interacción con el navegadorwindow.history
para usted con su navegador y sus historiales de hash. También proporciona un historial de memoria que es útil para entornos que no tienen un historial global. Esto es particularmente útil en el desarrollo de aplicaciones móviles (react-native
) y pruebas unitarias con Node.Una
history
instancia tiene dos métodos para navegar:push
yreplace
. Si piensa en elhistory
como un conjunto de ubicaciones visitadas,push
agregará una nueva ubicación al conjunto yreplace
reemplazará la ubicación actual en el conjunto con la nueva. Por lo general, querrá usar elpush
método cuando esté navegando.En versiones anteriores de React router, había que crear su propia
history
instancia, pero en la v4<BrowserRouter>
,<HashRouter>
y<MemoryRouter>
componentes crearán un navegador, hachís, y las instancias de memoria para usted. React Router hace que las propiedades y métodos de lahistory
instancia asociada con su enrutador estén disponibles a través del contexto, debajo delrouter
objeto.1. Use el
withRouter
componente de orden superiorEl
withRouter
componente de orden superior inyectará elhistory
objeto como accesorio del componente. Esto le permite acceder a los métodospush
yreplace
sin tener que lidiar concontext
.2. Use composición y renderice un
<Route>
El
<Route>
componente no es solo para ubicaciones coincidentes. Puede representar una ruta sin ruta y siempre coincidirá con la ubicación actual . El<Route>
componente pasa los mismos accesorios quewithRouter
, por lo que podrá acceder a loshistory
métodos a través delhistory
accesorio.3. Usa el contexto *
Pero probablemente no deberías
La última opción es una que solo debe usar si se siente cómodo trabajando con el modelo de contexto de React (la API de contexto de React es estable a partir de la versión 16).
1 y 2 son las opciones más simples de implementar, por lo que para la mayoría de los casos de uso, son sus mejores apuestas.
fuente
withRouter
lugar de pasarhistory
por todos mis componentes? Gahh necesito pasar más tiempo leyendo documentos ...history.push('/new-location')
sin asociar ese comportamiento a un botón u otro elemento DOM?Unexpected use of 'history' no-restricted-globals
context
ya no es experimental a partir de reaccionar 16.Puede usar el nuevo
useHistory
enlace en Componentes funcionales y navegar mediante programación:En 4.0 y versiones posteriores, use el historial como accesorio de su componente.
NOTA: this.props.history no existe en el caso de que su componente no haya sido procesado por
<Route>
. Deberías usar<Route path="..." component={YourComponent}/>
this.props.history en YourComponentEn 3.0 y superior, use el enrutador como accesorio de su componente.
En 2.4 y superiores, use un componente de orden superior para obtener el enrutador como accesorio de su componente.
Esta versión es compatible con versiones anteriores de 1.x, por lo que no hay necesidad de una Guía de actualización. Solo pasar por los ejemplos debería ser lo suficientemente bueno.
Dicho esto, si desea cambiar al nuevo patrón, hay un módulo de Historia del navegador dentro del enrutador al que puede acceder con
import { browserHistory } from 'react-router'
Ahora tiene acceso al historial de su navegador, por lo que puede hacer cosas como empujar, reemplazar, etc.
browserHistory.push('/some/path')
Lecturas adicionales: historias y navegación
No entraré en detalles de actualización. Puedes leer sobre eso en el Guía de actualización
El cambio principal sobre la pregunta aquí es el cambio de Navigation mixin a History. Ahora está usando el historial del navegador API para cambiar la ruta, así que usaremos
pushState()
de ahora en adelante.Aquí hay un ejemplo usando Mixin:
Tenga en cuenta que esto
History
proviene de rackt / history proyecto . No del propio React-Router.Si no desea usar Mixin por alguna razón (tal vez debido a la clase ES6), puede acceder al historial que obtiene del enrutador
this.props.history
. Solo será accesible para los componentes representados por su enrutador. Entonces, si desea usarlo en cualquier componente secundario, debe pasarlo como un atributo a través deprops
.Puede leer más sobre el nuevo lanzamiento en su documentación 1.0.x
Aquí está una página de ayuda específicamente sobre cómo navegar fuera de su componente
Recomienda tomar una referencia
history = createHistory()
y recurrirreplaceState
a eso.Me metí en el mismo problema y solo pude encontrar la solución con la combinación de navegación que viene con react-router.
Así es como lo hice
Pude llamar
transitionTo()
sin necesidad de acceder.context
O podrías probar el elegante ES6
class
React-Router-Redux tiene algunos métodos disponibles que permiten una navegación sencilla desde los creadores de acciones internas. Estos pueden ser particularmente útiles para las personas que tienen una arquitectura existente en React Native y desean utilizar los mismos patrones en React Web con una sobrecarga mínima.
Explore los siguientes métodos:
push(location)
replace(location)
go(number)
goBack()
goForward()
Aquí hay un ejemplo de uso, con Redux-Thunk :
./actioncreators.js
./viewcomponent.js
fuente
v2.4.0
pero el enfoque mencionado no funciona para mí, mi aplicación no se procesa en absoluto y las salidas de la consola:Uncaught TypeError: (0 , _reactRouter.withRouter) is not a function
aquí está el enlace a mi publicación SO: stackoverflow.com/questions/37306166/…2.6.0
.3.0.x
? Muchas personas parecen usar elcontext
camino.this.props.history
no existe en el caso de que su componente no haya sido procesado por<Route>
. Debe utilizar<Route path="..." component={YourComponent}/>
para tenerthis.props.history
enYourComponent
.Para la versión más reciente (
v2.0.0-rc5
), el método de navegación recomendado es presionar directamente sobre el singleton de historial. Puede ver eso en acción en el documento Navegación fuera de Componentes .Extracto relevante:
Si usa la API de enrutador reactivo más nueva, debe usar la
history
desdethis.props
adentro de los componentes para:También ofrece
pushState
pero eso está en desuso por advertencias registradas.Si lo usa
react-router-redux
, ofrece unapush
función que puede enviar de la siguiente manera:Sin embargo, esto solo se puede usar para cambiar la URL, no para navegar realmente a la página.
fuente
import { browserHistory } from './react-router'
sino que crea el historial usandoimport createBrowserHistory from 'history/lib/createBrowserHistory'
. Más adelante, puede accederhistory
desde los accesorios de los componentes:this.props.history('/some/path')
var browserHistory = require('react-router').browserHistory; browserHistory.goBack();
push
solo cambia la URL, en realidad no cambia la página. Para hacer las dos cosas, la importaciónbrowserHistory
dereact-router
usobrowserHistory.push('/my-cool-path')
. Desafortunadamente, esto no es muy fácil de encontrar. github.com/reactjs/react-router/blob/master/docs/guides/…react-router
v4Así es como se hace esto
react-router v2.0.0
con ES6 .react-router
se ha alejado de los mixins.fuente
history
singleton según lo indicado por @Bobby. Usted podría utilizarcontext.router
, pero lo estás haciendo muy difícil de probar la unidad dichos componentes como una instancia de solo ese componente no tendrá esto en el contexto.Por mi parte, me gusta tener un único objeto de historial que pueda transportar incluso componentes externos. Lo que me gusta hacer es tener un solo archivo history.js que importe bajo demanda y simplemente manipularlo.
Solo tiene que cambiar
BrowserRouter
a Enrutador y especificar el accesorio de historial. Esto no cambia nada para ti, excepto que tienes tu propio objeto de historial que puedes manipular como quieras.Necesita instalar el historial , la biblioteca utilizada por
react-router
.Ejemplo de uso, notación ES6:
history.js
BasicComponent.js
Si tiene que navegar desde un componente que realmente se representa desde un
Route
componente, también puede acceder al historial desde accesorios, de la siguiente manera:BasicComponent.js
fuente
Router
lugar deBrowserRouter
.BrowserRouter
crea y mantiene elhistory
objeto por ti. No debe crear de manera predeterminada la suya propia, solo si ["necesita una integración profunda con herramientas de administración de estado como Redux"]. Reacttraining.com/react-router/web/api/Routerthis.props.history
, todavía no he encontrado una solución que pueda ayudarme a hacer algo así en una clase que no sea un componente o cualquier otra herramienta que no esté construida como un componente React para el cual puedes pasar accesorios. Gracias por sus comentarios :)Para este, quién no controla el lado del servidor y debido a esto está usando el enrutador hash v2:
Coloque su historial en un archivo separado (por ejemplo, app_history.js ES6):
¡Y úsalo en todas partes!
Su punto de entrada para react-router (app.js ES6):
Su navegación dentro de cualquier componente (ES6):
fuente
history
cualquiera de los dos enfoques ahoratl: 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
withRouter
no funcionó cuando ya estaba en la ruta que se está volviendo a cargar. En nuestro caso, teníamos que hacer selectivamentesetState
(causarreturn <Redirect>
) si ya estábamos en la ruta ohistory.push()
desde otro lugar.Puedes hacer esto sin mixins también.
El problema con los contextos es que no es accesible a menos que defina
contextTypes
en la clase.En cuanto al contexto, es un objeto, como accesorios, que se transmiten de padres a hijos, pero se transmiten implícitamente, sin tener que volver a declarar los accesorios cada vez. Ver https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
fuente
¡Intenté al menos 10 formas de hacerlo antes de que algo funcionara bien!
La
withRouter
respuesta de @Felipe Skinner fue un poco abrumadora para mí, y no estaba segura de querer crear nuevos nombres de clase "ExportedWithRouter".Aquí está la forma más simple y limpia de hacerlo, alrededor del actual React-Router 3.0.0 y ES6:
o, si no es tu clase predeterminada, exporta como:
Tenga en cuenta que en 3.xx, el
<Link>
componente en sí está usandorouter.push
, por lo que puede pasarle cualquier cosa que le pase a la<Link to=
etiqueta, como:fuente
200 OK
lugar de30x
código. ¿Cómo puedo solucionar este problema?Para hacer la navegación mediante programación, es necesario impulsar una nueva historia a la props.history en su
component
, así que algo como esto puede hacer el trabajo por usted:fuente
Para los componentes ES6 + React, la siguiente solución funcionó para mí.
Seguí a Felippe Skinner, pero agregué una solución integral para ayudar a los principiantes como yo.
A continuación se muestran las versiones que utilicé:
A continuación se muestra mi componente de reacción donde utilicé la navegación programática usando react-router:
A continuación se muestra la configuración de mi enrutador:
fuente
Puede que no sea el mejor enfoque, pero ... Usando react-router v4, el siguiente mecanografiado podría dar una idea para algunos.
En el componente representado a continuación, por ejemplo
LoginPage
,router
se puede acceder al objeto y solo debe llamarrouter.transitionTo('/homepage')
para navegar.El código de navegación fue tomado de .
"react-router": "^4.0.0-2",
"react": "^15.3.1",
fuente
Puedes usar
withRouter
ythis.props.history.push
.fuente
Para usar
withRouter
con un componente basado en clases, intente algo como esto a continuación. No olvide cambiar la declaración de exportación para usarwithRouter
:import { withRouter } from 'react-router-dom'
fuente
basado en la respuesta anterior
de José Antonio Postigo y Ben Wheeler
la novedad? debe escribirse en mecanografiado
y el uso de decoradores
O propiedad / campo estático
con cualquier npm instalado hoy. "react-router": "^ 3.0.0" y
"@ types / react-router": "^ 2.0.41"
fuente
Con React-Router v4 en el horizonte, ahora hay una nueva forma de hacerlo.
react-lego es una aplicación de ejemplo que muestra cómo usar / actualizar react-router e incluye ejemplos de pruebas funcionales que navegan por la aplicación.
fuente
En reaccionar router v4. Sigo este camino de dos vías mediante programación.
Número dos
Para obtener el historial de accesorios, es posible que deba envolver su componente con
fuente
Si está utilizando hash o historial del navegador, puede hacerlo
fuente
hashHistory.push
, no puede leer la propiedad "push" de undefined. ¿De dónde importan estos?Con la versión actual de React (15.3),
this.props.history.push('/location');
funcionó para mí, pero mostró la siguiente advertencia:y lo resolví usando
context.router
así:fuente
React-Router V4
si está utilizando la versión 4, entonces puede usar mi biblioteca (Shameless plug) donde simplemente envía una acción y ¡todo funciona!
trippler
fuente
Aquellos que enfrentan problemas para implementar esto en react-router v4.
Aquí hay una solución de trabajo para navegar a través de la aplicación react desde acciones redux.
history.js
App.js / Route.jsx
otro_archivo.js O archivo redux
Todo gracias a este comentario: comentario de problemas de ReactTraining
fuente
Si empareja RR4 w / redux a través de react-router-redux , use también la
react-router-redux
opción de creadores de acciones de enrutamiento .Si usa redux thunk / saga para administrar el flujo asíncrono, importe los creadores de acciones anteriores en acciones redux y enganche para reaccionar componentes usando mapDispatchToProps podría ser mejor.
fuente
react-router-redux
ha quedado en desuso / archivado por un largo tiempoTambién puede usar el
useHistory
gancho en un componente sin estado. Ejemplo de los documentos.fuente
La respuesta correcta fue para mí al momento de escribir
Pero necesita agregar PropTypes a su componente
No olvides importar PropTypes
fuente
Quizás no sea la mejor solución, pero hace el trabajo:
Básicamente, una lógica vinculada a una acción (en este caso, una eliminación posterior) terminará llamando a un disparador para redireccionar. Esto no es ideal porque agregará un 'disparador' del nodo DOM a su marcado solo para que pueda llamarlo convenientemente cuando sea necesario. Además, interactuará directamente con el DOM, que en un componente React puede no ser deseado.
Aún así, este tipo de redireccionamiento no se requiere con tanta frecuencia. Por lo tanto, uno o dos enlaces ocultos adicionales en el marcado de su componente no afectarían tanto, especialmente si les da nombres significativos.
fuente
Esto funcionó para mí, no se necesitan importaciones especiales:
fuente
history
agregadoprops
solo. Eso proviene de un HoC que necesitarías importar para usar (los componentes enviados directamente porRoute
son envueltos automáticamente por ese HoC pero luego necesitas una importación paraRoute
...)use hookrouter en su lugar, la alternativa moderna al router de reacción
https://www.npmjs.com/package/hookrouter
para responder la pregunta de OP sobre el enlace a través del cuadro de selección, puede hacerlo:
fuente
Suponiendo que no necesitará navegar durante el renderizado inicial (para el cual puede usar el
<Redirect>
componente), esto es lo que estamos haciendo en nuestra aplicación.Defina una ruta vacía que devuelva nulo, esto le permitirá obtener acceso al objeto de historial. Debe hacer esto en el nivel superior donde su
Router
se define su.Ahora usted puede hacer todas las cosas que se pueden hacer en la historia como
history.push()
,history.replace()
,history.go(-1)
etc!fuente
react-router-dom: 5.1.2
Este sitio tiene 3 páginas, todas las cuales se representan dinámicamente en el navegador.
Aunque la página nunca se actualiza, observe cómo React Router mantiene la URL actualizada mientras navega por el sitio. Esto conserva el historial del navegador, asegurando que cosas como el botón de retroceso y los marcadores funcionen correctamente
Un conmutador examina todos sus elementos secundarios y muestra el primero cuya ruta coincide con la URL actual. Use una en cualquier momento que tenga varias rutas, pero solo desea que una de ellas se procese a la vez
fuente
Entonces, en mi respuesta, hay 3 formas diferentes de redirigir programáticamente a una ruta. Algunas de las soluciones ya se han presentado, pero las siguientes se centraron solo en componentes funcionales. con una aplicación de demostración adicional.
Usando las siguientes versiones:
Configuración:
Entonces, en primer lugar, está utilizando la solución
HashRouter
, configurada de la siguiente manera:De la documentación sobre
<HashRouter>
:Soluciones:
<Redirect>
para empujar usandouseState
:Usando en un componente funcional (
RedirectPushAction
componente de mi repositorio) podemos usaruseState
para manejar la redirección. La parte difícil es que una vez que se produjo la redirección, debemos volver a establecer elredirect
estadofalse
. Al usarsetTimeOut
con0
retraso estamos esperando hasta que React se comprometaRedirect
con el DOM y luego recuperemos el botón para usarlo la próxima vez.Por favor encuentre mi ejemplo a continuación:
De la
<Redirect>
documentación:useHistory
gancho:En mi solución hay un componente llamado
UseHistoryAction
que representa lo siguiente:withRouter
, obtenga elhistory
deprops
:Creado un componente llamado
WithRouterAction
, se muestra a continuación:Lectura de la
withRouter
documentación:Manifestación:
Para una mejor representación, he creado un repositorio de GitHub con estos ejemplos, por favor encuéntrelo a continuación:
https://github.com/norbitrial/react-router-programmatic-redirect-examples
¡Espero que esto ayude!
fuente