reactjs - example - react router redux 4
Mostrar el cuadro de diálogo personalizado setRouteLeaveHook o history.listenAntes de reaccionar-enrutador/redux? (1)
No puedo entender cómo mostrar un diálogo personalizado en lugar de utilizar la window.confirm
normal. window.confirm
que routeWillLeave
e history.listenBefore
usos. Básicamente, he creado un sistema de notificación y verifico si un formulario está sucio const { dispatch, history, dirty } = this.props;
si el formulario está sucio, significa que el usuario tiene cambios no guardados. Si cambian la ruta, me gustaría mostrar mi notificación que tendrá dos botones STAY
, IGNORE
y ambos pueden tomar un controlador onClick.
He pasado un tiempo buscando en Google y no he encontrado ninguna mención de cómo podría lograr esto usando routeWillLeave
. Lo más cercano que pude encontrar fue utilizar history.listenBefore
haya docs dicen que necesito hacer esto.
let history = createHistory({
getUserConfirmation(message, callback) {
callback(window.confirm(message)) // The default behavior
}
})
Pero estoy usando browserHistory desde reaction-router para iniciar mi store const history = syncHistoryWithStore(browserHistory, store);
¿Cómo puedo detener un cambio de ruta después de haber hecho clic en un enlace, mostrar una notificación usando mi sistema de notificación personalizado y, dependiendo de qué botón, haga clic en la transición a la nueva ruta o en la opción de permanecer?
Aquí hay un ejemplo de cómo funciona mi sistema de notificación y la dirección en la que me he dirigido, lo que obviamente no funciona porque todo lo que devuelve es una cadena para mostrar en la ventana. Confirme el diálogo de forma predeterminada.
history.listenBefore((location) => {
if(this.props.dirty){
const acceptBtn = {
title: ''STAY'',
handler: ignoreRouteChange() //This can be any function I want
}
const denyBtn = {
title: ''IGNORE'',
handler: continueRouteChange() //This can be any function I want
}
return dispatch(addNotification({
message: ''You have unsaved changes!'',
type: NOTIFICATION_TYPE_WARNING,
duration: 0,
canDismiss: false,
acceptBtn,
denyBtn
}));
return "Usaved changes!"
}
});
Gracias
Otra solución que he decidido usar es devolver falsa en la devolución de llamada setRouterLeaveHook normal y luego mostrar mi diálogo y usar la siguiente ubicación pasada a la devolución de llamada para presionar la siguiente ruta dependiendo de la selección del botón.
router.setRouteLeaveHook(route, this.routerWillLeave.bind(this));
routerWillLeave(nextLocation){
let { dirty, dispatch, resetForm } = this.props;
if (dirty) {
let dialog = {
id: Date.now(),
showTitle: true,
titleContent: ''Unsaved Changes'',
titleIcon: ''fa fa-warning'',
content: <span>You have <strong>unsaved</strong> changes! <strong>Discard</strong> them?</span>,
type: ''confirm'',
handleCloseClick: (e) => {
e.preventDefault();
dispatch(closeDialog());
},
acceptBtn: {
title: ''Okay'',
handler: (e) => {
e.preventDefault();
resetForm();
// Wait for call stack to unwind and then execute
// the following which will now have the updated values.
setTimeout(() => {
dispatch(push(nextLocation));
dispatch(closeDialog());
}, 0);
}
},
denyBtn: {
title: ''Deny'',
handler: (e) => {
e.preventDefault();
dispatch(closeDialog());
}
}
}
dispatch(addDialogWindow(dialog));
dispatch(openDialog(false, (e) => dispatch(closeDialog()), false));
return false;
}
return true;
}