使用从“next/router”导入的 NextJS13,SingletonRouter 为 Null

问题描述 投票:0回答:2

背景

当用户离开页面而不保存更改时,我试图取消路由更改。为了在 Next.js 中实现这一点,我需要监听路由更改并使用处理函数作为中间件来取消它们来拦截路由更改

像这样:

import { Router } from 'next/router'

Router.events.on('routeChangeStart', handleChange)

为了监听并发出处理函数作为中间件来拦截路由更改

问题

我知道 NextJS 在“next/navigation”中引入了一个新的 Router。但是,当我尝试从“next/router”导入旧路由器时,如下所示:

import SingletonRouter from 'next/router';

单例显示

null

我需要访问该单例以防止路由更改。

我需要访问该路由器单例以防止路由更改。

next.js next.js13
2个回答
0
投票

首先..如果您使用应用程序路由器。您需要使用下一步/导航。如果使用pages目录,可以使用next/router包。

设置状态来跟踪更改:首先,管理一个状态变量来跟踪是否有未保存的更改。

import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';

function YourComponent() {
    const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
    const router = useRouter();


    const toggleUnsavedChanges = () => setHasUnsavedChanges(!hasUnsavedChanges);
}

使用beforePopState方法拦截路由变化。您可以通过确认对话框提示用户,以确保他们想要离开未保存更改的页面。

    useEffect(() => {
        const handleRouteChange = (url) => {
            if (router.asPath !== url && hasUnsavedChanges) {
                if (window.confirm('You have unsaved changes, are you sure you want to leave?')) {
                    // Allow the route change
                    return true;
                } else {
                    // Prevent the route change
                    router.events.emit('routeChangeError');
                    throw 'Route change aborted.';
                }
            }
        }

        router.beforePopState(handleRouteChange);

        return () => {
            router.beforePopState(() => true); // Clean up the listener
        };
    }, [hasUnsavedChanges, router]);

您需要根据影响是否存在未保存更改的用户交互来调整状态。例如,修改表单字段会将 hasUnsavedChanges 设置为 true。


0
投票

SingletonRouter 存在于使用
pages
目录的 Next 13 中

您将能够从

Router
访问
'next/router"
旧版挂钩模块,但要访问
SingletonRouter
来发出事件,您必须使用
pages
文件夹结构进行路由,而不是
app
文件夹。

“下一步/导航”中的新

Router
不允许您阻止路由。

作为一种解决方法,我发现一些 Next.js 项目混合了页面文件夹和应用程序文件夹,但我不推荐这种方法。

© www.soinside.com 2019 - 2024. All rights reserved.