gpt4 book ai didi

javascript - React Router v5.2 - 使用 createBrowserHistory 和 history.block 阻止路由更改

转载 作者:行者123 更新时间:2023-12-04 14:32:42 26 4
gpt4 key购买 nike

我的应用有两个页面:Step1Step2 . Step1有一个复选框,如果选中则阻止导航,还有一个导航到 Step2 的下一步按钮点击时。 Step2有一个返回 Step1 的上一个按钮点击时。
Link to demo
据此tutorial , 我正在使用 block createBrowserHistory 的方法如果 Step1 中的复选框,则阻止路由更改的对象检查:

const unblock = useRef();

useEffect(() => {
unblock.current = history.block((tx) => {
if (block.current.checked) {
const promptMessage = "Are you sure you want to leave?";

if (window.confirm(promptMessage)) {
unblock.current();
tx.retry();
}
} else {
console.log("tfgx");
unblock.current();
tx.retry();
}
});
}, []);
我还必须在低级 <Router> 中设置历史 Prop (不是 <BrowserRouter> )到 createBrowserHistory对象,像这样:
<Router history={createBrowserHistory()}>
...
</Router>
但这会阻止路线正确呈现 .我认为这可能与 <Switch> 有关无法正确读取位置对象。如果我使用 <BrowserRouter> ,位置对象如下所示: {pathname: "/step1", ... key: "7sd45"} .但是当我使用 <Router={createBrowserHistory()}> ,位置对象看起来像这样 {action: "PUSH", location: {pathname: "/step1", ... key: "7sd45"}} . (我也收到警告 You cannot change <Router history> 。)
如果选中“阻止导航”复选框,我想要的结果是阻止导航,否则取消阻止。如果导航畅通时位置发生变化,我希望正确呈现相应的路线。
React Router v5 文档中关于 createBrowserHisory 的部分很少,并且没有很多使用它的示例,所以如果有人能对此有所了解,我将不胜感激。

编辑:路过 location.location<Switch>似乎可以修复它( Updated demo )。但是如果我调用 useLocation里面 Step1并打印结果(第 17-18 行),我得到 {pathname: "/step1", ... key: "7sd45"}而不是 {action: "PUSH", location: {pathname: "/step1", ... key: "7sd45"}} . 为什么是这样?
此外,如果用户在导航被阻止时尝试去另一个位置,我的自定义提示会按预期显示(“您确定要离开”,带有“确定”和“取消”按钮)。但是,如果他们通过单击取消取消此操作,则会出现浏览器自己的对话框 -
在 Chrome 中:
enter image description here
在火狐中:
enter image description here
在我的提示被解除后是否可以禁止浏览器提示?

最佳答案

路由器上下文的 history object 也有一个 block 功能,但它的工作方式略有不同。它需要一个消耗 location 的回调和 action论据。

history.block((location, action) => {...});
返回 false从回调阻止导航转换,返回 true允许过渡通过。
React.useEffect(() => {
const unblock = history.block((location, action) => {
if (checkBlockingCondition) {
return window.confirm("Navigate Back?");
}
return true;
});

return () => {
unblock();
};
}, []);
或者,react-router-dom 建议使用 Prompt有条件地阻止路由转换的组件。您的代码非常接近他们的 preventing transitions例子。
更新您的最后一个代码框:
  • 使用阻塞状态与 react 引用,以便提示重新呈现并重新评估条件。
  • 渲染 Prompt零件。
  • 阻止默认的表单提交操作,即阻止页面重新加载。

  • 代码
    import {
    BrowserRouter as Router,
    Prompt, // <-- import Prompt
    Redirect,
    Switch,
    Route,
    useLocation
    } from "react-router-dom";

    const Step1 = ({ id, history }) => {
    const [isBlocking, setIsBlocking] = useState(false);

    return (
    <form
    id={id}
    onSubmit={(e) => {
    e.preventDefault(); // <-- prevent default form action, i.e. page reload
    history.push("/step2");
    }}
    >
    <label>
    Block navigation
    <input
    type="checkbox"
    onChange={(e) => setIsBlocking(e.target.checked)}
    />
    </label>
    <br />
    <br />
    <button type="submit">Next</button>
    <Prompt
    when={isBlocking} // <-- blocking condition
    message="Are you sure you want to leave?"
    />
    </form>
    );
    };
    Edit react-router-v5-2-blocking-route-change-with-createbrowserhistory-and-history

    关于javascript - React Router v5.2 - 使用 createBrowserHistory 和 history.block 阻止路由更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65526447/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com