React Router v.6 usePrompt TypeScript

React Router v.6 usePrompt TypeScript

我基本上是在尝试拦截路由更改。也许与 React Router v6 中 vue 的 beforeEach 等价的东西可能有用,因为 React Router v.6 not include usePrompt.

在每次更改路线之前,我想做一些逻辑 - 该逻辑可能需要根据结果中断甚至更改结束路线。

我四处搜索,但我真的找不到解决这个具体问题的方法。

提前致谢。

目前他们已经从 react-router v6.

中删除了 usePrompt

我从 ui.dev 找到了一个解决方案并添加了 TypeScript 支持,现在我正在使用它直到 react-router 将带回 usePrompt/useBlocker 钩子

import { History, Transition } from 'history';
import { useCallback, useContext, useEffect } from "react";
import { UNSAFE_NavigationContext as NavigationContext } from "react-router-dom";

type ExtendNavigator = Navigator & Pick<History, "block">;
export function useBlocker(blocker: (tx: Transition) => void, when = true) {
    const { navigator } = useContext(NavigationContext);

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

        const unblock = (navigator as any as ExtendNavigator).block((tx) => {
            const autoUnblockingTx = {
                ...tx,
                retry() {
                    unblock();
                    tx.retry();
                },
            };

            blocker(autoUnblockingTx);
        });

        return unblock;
    }, [navigator, blocker, when]);
}

export default function usePrompt(message: string, when = true) {
    const blocker = useCallback((tx: Transition) => {
        if (window.confirm(message)) tx.retry();
    }, [message]);

    useBlocker(blocker, when);
}

然后可以在任何 view/component 条件为真时显示“A you sure you want to leave?”的消息中使用。

usePrompt("Do you want to leave?", isFormDirty());