【发布时间】:2021-12-09 10:22:33
【问题描述】:
在导航到 ReactJS Web 应用程序中的其他路由或页面之前,我正在尝试显示未保存更改的对话框。我尝试了与 Stackoverflow 不同的解决方案,但没有成功。大多数解决方案与旧版本有关。我需要版本 6.0.2 (react-router-dom)。任何可以帮助我的人都非常感激。
【问题讨论】:
标签: javascript reactjs react-router react-router-dom
在导航到 ReactJS Web 应用程序中的其他路由或页面之前,我正在尝试显示未保存更改的对话框。我尝试了与 Stackoverflow 不同的解决方案,但没有成功。大多数解决方案与旧版本有关。我需要版本 6.0.2 (react-router-dom)。任何可以帮助我的人都非常感激。
【问题讨论】:
标签: javascript reactjs react-router react-router-dom
如果有任何未保存的更改(例如未保存的表单元素),您可以使用usePrompt 或useBlocker 检测并在离开另一条路线之前显示提示。
但是,在 react router v6 的 official 文档中提到了以下内容:
来自 v5(以及来自 v6 的 usePrompt 和 useBlocker betas) 不包含在当前发布的 v6 版本中。
我也在 Github 上查看过,即使是当前版本 6.2.1 也不支持usePrompt 和useBlocker。
但您仍然可以降级到 v5 或 6.0.0-alpha.5 以下代码适用于反应路由器 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>
);
}
【讨论】:
如何解决我的问题? 我没有降级,而是创建了两个自定义挂钩。
useCallbackPrompt钩子useBlocker钩子useCallbackPrompt钩子
这个钩子处理一个弹出窗口,根据特定条件显示、隐藏和更新位置。
它看起来如何。
我创建了状态showDialog;如果用户更改当前页面/表单上的某些内容,它将更新状态showDialog,如果用户试图离开,则会显示提示,并询问用户是否想留下。
Post的链接
【讨论】: