react-router-dom x6
版本中移除了prompt 离开组件 拦截的方法
在开发中遇到这个问题,记录下
import { useContext, useEffect, useCallback } from "react";
import { UNSAFE_NavigationContext as NavigationContext } from "react-router-dom";
export function useBlocker(blocker, when = true) {
const { navigator } = useContext(NavigationContext);
useEffect(() => {
if (!when) return;
const unblock = navigator.block((tx) => {
const autoUnblockingTx = {
...tx,
retry() {
unblock();
tx.retry();
},
};
blocker(autoUnblockingTx);
});
return unblock;
}, [navigator, blocker, when]);
}
export function usePrompt(message, when = true) {
const { basename } = useContext(NavigationContext);
const blocker = useCallback((tx) => {
if (typeof message === "function") {
let targetLocation = tx?.location?.pathname;
if (targetLocation.startsWith(basename)) {
targetLocation = targetLocation.substring(basename.length);
}
if (message(targetLocation)) {
tx.retry();
}
} else if (typeof message === "string") {
// eslint-disable-next-line no-alert
if (window.confirm(message)) {
tx.retry();
}
}
}, [message, basename]);
return useBlocker(blocker, when);
}
使用方式
首先在需要拦截的组件中引用 usePrompt 方法
import { usePrompt } from "../aaa";
然后在你的 组件中 使用
传递函数:第二个参数一般是业务 判断出来的结果,true的时候会出现弹框拦截,false 则不会
usePrompt(function () {
console.log('操作')
}, true);
直接使用,第一个是提示语句,第二个同上
usePrompt(‘内容未保存,是否取消?’, true);