如果我的页面在react-router-domV6中有未保存的更改(isDirty: true),我能够捕获推送事件并控制导航,而我不能为POP事件包装我的头.似乎navigatorNavigationContext没有直接expose 的流行事件使用.有谁能帮忙吗?

我的推送事件代码如下所示-

import { useEffect } from 'react';
import { UNSAFE_NavigationContext as NavigationContext } from 'react-router-dom';

const useConfirmExit = function (confirmExit: () => Promise<boolean>, when = true, callbackfn: (arg0: any) => void): void {
    const {navigator} = useContext(NavigationContext);

    useEffect(() => {
        if (!when) {
            return () => { };
        }

        const {go, push} = navigator;

        navigator.push = async (...args: Parameters<typeof push>) => {
            const result = await confirmExit();
            if (result !== false) {
                callbackfn(arg0);
                push(...args);
            }
        };
        
        navigator.go = async (delta: number) => {
            const result = await confirmExit();
            if (result !== false) {
                go(delta);
            }
        };

        return () => {
            navigator.push = push;
            navigator.go = go;
        };
    }, [navigator, confirmExit, when]);
}; 

confirmExit只是另一个异步函数,它接受用户的输入,如果他们想要导航离开未保存的页面.

推荐答案

navigator没有任何导航操作,例如按下、弹出、替换,但它具有go功能,可以在历史堆栈中向前/向后移动.navigator.go(-1)goBack或反向导航的同义词.

/**
 * A Navigator is a "location changer"; it's how you get to different locations.
 *
 * Every history instance conforms to the Navigator interface, but the
 * distinction is useful primarily when it comes to the low-level <Router> API
 * where both the location and a navigator must be provided separately in order
 * to avoid "tearing" that may occur in a suspense-enabled app if the action
 * and/or location were to be read directly from the history instance.
 */
export interface Navigator {
  createHref: History["createHref"];
  // Optional for backwards-compat with Router/HistoryRouter usage (edge case)
  encodeLocation?: History["encodeLocation"];
  go: History["go"];
  push(to: To, state?: any, opts?: NavigateOptions): void;
  replace(to: To, state?: any, opts?: NavigateOptions): void;
}

您也可以增加go函数,如下所示:

import { useEffect } from 'react';
import { UNSAFE_NavigationContext as NavigationContext } from 'react-router-dom';

function useConfirmExit(confirmExit: () => Promise<boolean>, when = true): void {
  const { navigator } = useContext(NavigationContext);

  useEffect(() => {
    if (!when) {
      return () => { };
    }

    const { go, push } = navigator;

    navigator.go = async (delta: number) => {
      const result = await confirmExit();
      if (result !== false) {
        console.log('Save to be invoked');
        go(delta);
      }
    };

    navigator.push = async (...args: Parameters<typeof push>) => {
      const result = await confirmExit();
      if (result !== false) {
        console.log('Save to be invoked');
        push(...args);
      }
    };
        
    return () => {
      navigator.go = go;
      navigator.push = push;
    };
  }, [navigator, confirmExit, when]);
}

Typescript相关问答推荐

如何从TypScript中的接口中正确获取特定键类型的所有属性?

如何正确修复TypScript 4.7到4.8升级中的TS 2345编译错误

如何使类型只能有来自另一个类型的键,但键可以有一个新值,新键应该抛出一个错误

替代语法/逻辑以避免TS变量被分配之前使用." "

在将对象从一个对象转换成另一个对象时,可以缩小对象的键吗?

如果一个变量不是never类型,我如何创建编译器错误?

动态调用类型化函数

泛型类型,引用其具有不同类型的属性之一

TypeScrip 5.3和5.4-对`Readonly<;[...number[],字符串]>;`的测试版处理:有什么变化?

如何在Reaction路由v6.4加载器和操作中获得Auth0访问令牌?

在分配给类型的只读变量中维护const的类型

在类型脚本中创建泛型类型以动态追加属性后缀

有没有办法取消分发元组的联合?

在正常函数内部调用异步函数

如果判断空值,则基本类型Gaurd不起作用

如何在Nextjs路由处理程序中指定响应正文的类型

如何正确键入泛型相对记录值类型?

将带有额外id属性的Rust struct 展平回TypeScript单个对象,以返回wasm-bindgen函数

通用可选函数参数返回类型

创建通过删除参数来转换函数的对象文字的类型