I'm trying to intercept route changing based on boolean
value(if there are unsaved changes).
I found the topic related discussions and tried to implement, but it doesn't work properly.
Clicking Cancel
button throws this error
TypeError: Cannot read properties of undefined (reading 'shallow')
const routeChangeStart = (url: string) => {
55 | if (Router.asPath !== url && unsavedChanges && !confirm(message)) {
> 56 | Router.events.emit('routeChangeError')
| ^
57 | Router.replace(Router, Router.asPath)
58 | throw 'Abort route change. Please ignore this error.'
59 | }
Furthermore, clicking the cancel
button it will change the url 1 step back. Let's say my url is localhost:3000/products/10
, it will become localhost:3000/products
and throw the error described above.
I'm not sure if it's the best approach, or it's possible only with next.js router
, I mean without global window properties
, so any help will be appreciated.
Topic related code snippet below.
import Router from 'next/router'
.....
////
const [unsavedChanges, setUnsavedChanges] = useState<boolean>(true)
const message = 'Do you want to leave?'
useEffect(() => {
const routeChangeStart = (url: string) => {
if (Router.asPath !== url && unsavedChanges && !confirm(message)) {
Router.events.emit('routeChangeError')
Router.replace(Router, Router.asPath)
throw 'Abort route change. Please ignore this error.'
}
}
const beforeunload = (e: any) => {
if (unsavedChanges) {
e.preventDefault()
e.returnValue = message
return message
}
}
window.addEventListener('beforeunload', beforeunload)
Router.events.on('routeChangeStart', routeChangeStart)
return () => {
window.removeEventListener('beforeunload', beforeunload)
Router.events.off('routeChangeStart', routeChangeStart)
}
}, [unsavedChanges])