Con react-routerpuedo usar el Linkelemento 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 Navigationmixin, pero ¿puedo hacer esto sin mixins?
reactjs
react-router
George Mauer
fuente
fuente

Respuestas:
Hay un nuevo
useHistorygancho 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.
withRoutercomponente de orden superior.<Route>context.React Router es principalmente un contenedor alrededor de la
historybiblioteca.historymaneja la interacción con el navegadorwindow.historypara 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
historyinstancia tiene dos métodos para navegar:pushyreplace. Si piensa en elhistorycomo un conjunto de ubicaciones visitadas,pushagregará una nueva ubicación al conjunto yreplacereemplazará la ubicación actual en el conjunto con la nueva. Por lo general, querrá usar elpushmétodo cuando esté navegando.En versiones anteriores de React router, había que crear su propia
historyinstancia, 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 lahistoryinstancia asociada con su enrutador estén disponibles a través del contexto, debajo delrouterobjeto.1. Use el
withRoutercomponente de orden superiorEl
withRoutercomponente de orden superior inyectará elhistoryobjeto como accesorio del componente. Esto le permite acceder a los métodospushyreplacesin 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 loshistorymétodos a través delhistoryaccesorio.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
withRouterlugar de pasarhistorypor 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-globalscontextya no es experimental a partir de reaccionar 16.Puede usar el nuevo
useHistoryenlace 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
Historyproviene 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 recurrirreplaceStatea 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.contextO podrías probar el elegante ES6
classReact-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.0pero 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 functionaquí está el enlace a mi publicación SO: stackoverflow.com/questions/37306166/…2.6.0.3.0.x? Muchas personas parecen usar elcontextcamino.this.props.historyno existe en el caso de que su componente no haya sido procesado por<Route>. Debe utilizar<Route path="..." component={YourComponent}/>para tenerthis.props.historyenYourComponent.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
historydesdethis.propsadentro de los componentes para:También ofrece
pushStatepero eso está en desuso por advertencias registradas.Si lo usa
react-router-redux, ofrece unapushfunció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 accederhistorydesde los accesorios de los componentes:this.props.history('/some/path')var browserHistory = require('react-router').browserHistory; browserHistory.goBack();pushsolo cambia la URL, en realidad no cambia la página. Para hacer las dos cosas, la importaciónbrowserHistorydereact-routerusobrowserHistory.push('/my-cool-path'). Desafortunadamente, esto no es muy fácil de encontrar. github.com/reactjs/react-router/blob/master/docs/guides/…react-routerv4Así es como se hace esto
react-router v2.0.0con ES6 .react-routerse ha alejado de los mixins.fuente
historysingleton 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
BrowserRoutera 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
Routecomponente, también puede acceder al historial desde accesorios, de la siguiente manera:BasicComponent.js
fuente
Routerlugar deBrowserRouter.BrowserRoutercrea y mantiene elhistoryobjeto 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
historycualquiera 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
withRouterno 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
contextTypesen 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
withRouterrespuesta 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 OKlugar de30xcó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,routerse 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
withRouterythis.props.history.push.fuente
Para usar
withRoutercon 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.routerasí: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-reduxopció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-reduxha quedado en desuso / archivado por un largo tiempoTambién puede usar el
useHistorygancho 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
historyagregadopropssolo. Eso proviene de un HoC que necesitarías importar para usar (los componentes enviados directamente porRouteson 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
Routerse 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 (
RedirectPushActioncomponente de mi repositorio) podemos usaruseStatepara manejar la redirección. La parte difícil es que una vez que se produjo la redirección, debemos volver a establecer elredirectestadofalse. Al usarsetTimeOutcon0retraso estamos esperando hasta que React se comprometaRedirectcon 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:useHistorygancho:En mi solución hay un componente llamado
UseHistoryActionque representa lo siguiente:withRouter, obtenga elhistorydeprops:Creado un componente llamado
WithRouterAction, se muestra a continuación:Lectura de la
withRouterdocumentació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