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());
我基本上是在尝试拦截路由更改。也许与 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());