在 Next 如何在 Next JS 中停止路由器导航。
我正在尝试使用routerChangeStart事件来停止导航。
useEffect(() => {
const handleRouteChange = (url: string): boolean => {
if (dirty) {
return false;
}
return true;
};
Router.events.on('routeChangeStart', handleRouteChange);
return () => {
Router.events.off('routeChangeStart', handleRouteChange);
};
}, []);
Run Code Online (Sandbox Code Playgroud)
rai*_*ska 19
这是我的自定义钩子解决方案,它是用 TypeScript 编写的,似乎很有效。
import Router from "next/router"
import { useEffect } from "react"
const useWarnIfUnsavedChanges = (unsavedChanges: boolean, callback: () => boolean) => {
useEffect(() => {
if (unsavedChanges) {
const routeChangeStart = () => {
const ok = callback()
if (!ok) {
Router.events.emit("routeChangeError")
throw "Abort route change. Please ignore this error."
}
}
Router.events.on("routeChangeStart", routeChangeStart)
return () => {
Router.events.off("routeChangeStart", routeChangeStart)
}
}
}, [unsavedChanges])
}
Run Code Online (Sandbox Code Playgroud)
您可以在组件中使用它,如下所示:
useWarnIfUnsavedChanges(changed, () => {
return confirm("Warning! You have unsaved changes.")
})
Run Code Online (Sandbox Code Playgroud)
小智 7
您可以编写自定义挂钩。
import Router from 'next/router';
import { useEffect } from 'react';
const useWarnIfUnsavedChanges = (unsavedChanges, callback) => {
useEffect(() => {
const routeChangeStart = url => {
if (unsavedChanges) {
Router.events.emit('routeChangeError');
Router.replace(Router, Router.asPath, { shallow: true });
throw 'Abort route change. Please ignore this error.';
}
};
Router.events.on('routeChangeStart', routeChangeStart);
return () => {
Router.events.off('routeChangeStart', routeChangeStart);
};
}, [unsavedChanges]);
};
export default useWarnIfUnsavedChanges;Run Code Online (Sandbox Code Playgroud)
从以下地方获取灵感:https ://github.com/vercel/next.js/discussions/12348#discussioncomment-8089
小智 5
似乎没有完美的方法,但我用这个小技巧来处理它:
React.useEffect(() => {
const confirmationMessage = 'Changes you made may not be saved.';
const beforeUnloadHandler = (e: BeforeUnloadEvent) => {
(e || window.event).returnValue = confirmationMessage;
return confirmationMessage; // Gecko + Webkit, Safari, Chrome etc.
};
const beforeRouteHandler = (url: string) => {
if (Router.pathname !== url && !confirm(confirmationMessage)) {
// to inform NProgress or something ...
Router.events.emit('routeChangeError');
// tslint:disable-next-line: no-string-throw
throw `Route change to "${url}" was aborted (this error can be safely ignored). See https://github.com/zeit/next.js/issues/2476.`;
}
};
if (notSaved) {
window.addEventListener('beforeunload', beforeUnloadHandler);
Router.events.on('routeChangeStart', beforeRouteHandler);
} else {
window.removeEventListener('beforeunload', beforeUnloadHandler);
Router.events.off('routeChangeStart', beforeRouteHandler);
}
return () => {
window.removeEventListener('beforeunload', beforeUnloadHandler);
Router.events.off('routeChangeStart', beforeRouteHandler);
};
}, [notSaved]);
Run Code Online (Sandbox Code Playgroud)
此代码将中断更改路由(使用 nextJs 路由以及浏览器刷新/关闭选项卡操作)
| 归档时间: |
|
| 查看次数: |
2548 次 |
| 最近记录: |