Quiero que mi aplicación ReactJS notifique a un usuario cuando navega fuera de una página específica. Específicamente, un mensaje emergente que le recuerda que debe realizar una acción:
"Los cambios se guardan, pero aún no se publican. ¿Hacer eso ahora?"
¿Debo activar esto react-router
globalmente, o es algo que se puede hacer desde la página / componente de reacción?
No he encontrado nada sobre este último y prefiero evitar el primero. A menos que sea la norma, por supuesto, pero eso me hace preguntarme cómo hacer tal cosa sin tener que agregar código a todas las demás páginas posibles a las que el usuario puede ir.
Cualquier información es bienvenida, ¡gracias!
reactjs
react-router
Barry Staes
fuente
fuente
componentWillUnmount() { if (confirm('Changes are saved, but not published yet. Do that now?')) { // publish and go away from a specific page } else { // do nothing and go away from a specific page } }
para que pueda llamar a su función de publicación antes de salir de la páginaRespuestas:
react-router
v4 introduce una nueva forma de bloquear la navegación usandoPrompt
. Simplemente agregue esto al componente que le gustaría bloquear:Esto bloqueará cualquier enrutamiento, pero no la actualización ni el cierre de la página. Para bloquear eso, deberá agregar esto (actualizando según sea necesario con el ciclo de vida apropiado de React):
onbeforeunload tiene varios tipos de compatibilidad con los navegadores.
fuente
onberforeunload
alerta.react-router
no admite eso de inmediato (asumiendo que el botón cancelar no activa ningún cambio de ruta). Sin embargo, puede crear su propio modal para imitar el comportamiento.onbeforeunload
, querrá limpiarlo cuando se desmonte su componente.componentWillUnmount() { window.onbeforeunload = null; }
En react-router
v2.4.0
o superior y antesv4
hay varias opcionesonLeave
paraRoute
setRouteLeaveHook
paracomponentDidMount
Puede evitar que se produzca una transición o avisar al usuario antes de abandonar una ruta con un gancho de salida.
Tenga en cuenta que este ejemplo hace uso del
withRouter
componente de orden superior introducido env2.4.0.
Sin embargo, esta solución no funciona a la perfección cuando se cambia la ruta en la URL manualmente
En el sentido de que
Para
react-router v4
usar el historial personalizado o Prompt:Sin embargo
react-router v4
, es bastante más fácil de implementar con la ayuda dePrompt
from'react-routerSegún la documentación
En su método de renderizado, simplemente necesita agregar esto como se menciona en la documentación de acuerdo con sus necesidades.
ACTUALIZAR:
En caso de que desee tener una acción personalizada para realizar cuando el uso está saliendo de la página, puede hacer uso del historial personalizado y configurar su enrutador como
history.js
y luego en su componente puede hacer uso de
history.block
likefuente
<Prompt>
la URL se cambia cuando presiona Cancelar en el mensaje. ProblemaPara
react-router
2.4.0+NOTA : Es recomendable migrar todo su código a la última versión
react-router
para obtener todas las novedades.Como se recomienda en la documentación de react-router :
Uno debe usar el
withRouter
componente de orden superior:Como ejemplo de ES6 de la documentación:
fuente
Para
react-router
v3.xTuve el mismo problema en el que necesitaba un mensaje de confirmación para cualquier cambio no guardado en la página. En mi caso, estaba usando React Router v3 , por lo que no pude usar
<Prompt />
, que se introdujo desde React Router v4 .Manejé 'hacer clic en el botón de retroceso' y 'clic accidental en un enlace' con la combinación de
setRouteLeaveHook
yhistory.pushState()
, y manejé 'botón de recarga' con elonbeforeunload
controlador de eventos.setRouteLeaveHook ( doc ) e history.pushState ( doc )
Usar solo setRouteLeaveHook no fue suficiente. Por alguna razón, se cambió la URL, aunque la página permaneció igual cuando se hizo clic en el botón "Atrás".
onbeforeunload ( doc )
Se utiliza para manejar el botón de 'recarga accidental'
A continuación se muestra el componente completo que he escrito
this.props.router
.this.props.route
se transmite desde el componente de llamadatenga en cuenta que
currentState
se pasa como prop para tener un estado inicial y para verificar cualquier cambioPor favor, avíseme si tiene alguna pregunta :)
fuente
Para
react-router
v0.13.x conreact
v0.13.x:esto es posible con los métodos estáticos
willTransitionTo()
ywillTransitionFrom()
. Para versiones más nuevas, vea mi otra respuesta a continuación.De la documentación de react-router :
Para
react-router
1.0.0-rc1 conreact
v0.14.xo posterior:esto debería ser posible con el
routerWillLeave
enlace del ciclo de vida. Para versiones anteriores, vea mi respuesta anterior.De la documentación de react-router :
Cosas. Sin embargo, puede cambiar antes del lanzamiento final.
fuente
Puede utilizar este mensaje.
fuente
Usando history.listen
Por ejemplo, como a continuación:
En su componente,
fuente