我试图在导航到 ReactJS Web 应用程序中的其他路线或页面之前显示未保存更改的对话框。我尝试了 Stackoverflow 的不同解决方案,但没有成功。大多数解决方案与旧版本相关。我需要版本6.0.2(react-router-dom)。任何能在这方面帮助我的人都非常感激。
如何解决我的问题? 我没有降级,而是创建了两个自定义挂钩。
useCallbackPrompt
挂钩useBlocker
挂钩useCallbackPrompt
挂钩
该挂钩处理弹出窗口,以根据特定条件显示、隐藏和更新位置。
看起来怎么样。
使用Blocker Hook 如果有任何更改,此挂钩会阻止用户导航离开
我创建了状态
showDialog
;如果用户更改当前页面/表单上的某些内容,它将更新状态showDialog
,如果用户尝试离开,则会显示提示,并询问用户是否想要留下。
这是现场演示链接
链接如果有任何未保存的更改(例如在未保存的表单元素中),您可以使用
usePrompt
或 useBlocker
在前往另一条路线之前检测并显示提示。
但是,在React Router v6的官方文档中提到了以下内容:
来自 v5(以及来自 v6 的 usePrompt 和 useBlocker betas)不包含在当前发布的 v6 版本中。
我也查了一下Github,目前的6.2.1版本都不支持
usePrompt
和useBlocker
。
但是您仍然可以降级到 v5 或 6.0.0-alpha.5 以下代码适用于 React Router v6.0.0-alpha.5
import React, { useState, useRef, useEffect } from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useHistory,
usePrompt,
useBlocker,
Routes
} from "react-router-dom";
// Sometimes you want to prevent the user from
// navigating away from a page. The most common
// use case is when they have entered some data
// into a form but haven't submitted it yet, and
// you don't want them to lose it.
export default function PreventingTransitionsExample() {
return (
<Router>
<ul>
<li>
<Link to="/">Form</Link>
</li>
<li>
<Link to="/one">One</Link>
</li>
<li>
<Link to="/two">Two</Link>
</li>
</ul>
<Routes>
<Route path="/" exact children={<BlockingForm />} />
<Route path="/one" children={<h3>One</h3>} />
<Route path="/two" children={<h3>Two</h3>} />
</Routes>
</Router>
);
}
function BlockingForm() {
let [isBlocking, setIsBlocking] = useState(false);
usePrompt(
"Hello from usePrompt -- Are you sure you want to leave?",
isBlocking
);
// useBlocker(
// () => "Hello from useBlocker -- are you sure you want to leave?",
// isBlocking
// );
return (
<form
onSubmit={event => {
event.preventDefault();
event.target.reset();
setIsBlocking(false);
}}
>
<p>
Blocking? {isBlocking ? "Yes, click a link or the back button" : "Nope"}
</p>
<p>
<input
size="50"
placeholder="type something to block transitions"
onChange={event => {
setIsBlocking(event.target.value.length > 0);
}}
/>
</p>
<p>
<button>Submit to stop blocking</button>
</p>
</form>
);
}