Open NemoZhong opened 1 year ago
π΅βπ«π΅βπ« both client side rendering and server side rendering in one page, routeChangeStart will not be triggered at service rendering.
Like the top answer, beforeunload
need to be listennedοΌbut its styles are different
import Router from 'next/router'
import { useEffect } from 'react'
import { Modal } from 'antd'
const { confirm } = Modal
const usePrompt = (flag: boolean, message: string) => {
useEffect(() => {
const beforeunloadHandler = (event) => {
event.preventDefault()
event.returnValue = message
}
const beforeRouteHandler = (url: string) => {
if (Router.pathname !== url) {
confirm({
title: message,
onOk: () => {
Router.events.off('routeChangeStart', beforeRouteHandler)
Router.push(url)
},
onCancel: () => {},
})
Router.events.emit('routeChangeError')
throw `Route change to "${url}" was aborted (this error can be safely ignored). See https://github.com/zeit/next.js/issues/2476.`
}
}
if (flag) {
Router.events.on('routeChangeStart', beforeRouteHandler)
window.addEventListener('beforeunload', beforeunloadHandler)
} else {
Router.events.off('routeChangeStart', beforeRouteHandler)
window.removeEventListener('beforeunload', beforeunloadHandler)
}
return () => {
Router.events.off('routeChangeStart', beforeRouteHandler)
window.removeEventListener('beforeunload', beforeunloadHandler)
}
}, [flag, message])
}
export default usePrompt
Next JS: Warn User for Unsaved Form before Route Change
πππ the only way to cancle route change is THROW ERROR!