使用react-router-dom v6.0.2检测用户离开页面

问题描述 投票:0回答:3

我试图在导航到 ReactJS Web 应用程序中的其他路线或页面之前显示未保存更改的对话框。我尝试了 Stackoverflow 的不同解决方案,但没有成功。大多数解决方案与旧版本相关。我需要版本6.0.2(react-router-dom)。任何能在这方面帮助我的人都非常感激。

javascript reactjs react-router react-router-dom
3个回答
8
投票

如何解决我的问题? 我没有降级,而是创建了两个自定义挂钩。

  1. useCallbackPrompt
    挂钩
  2. useBlocker
    挂钩

useCallbackPrompt
挂钩 该挂钩处理弹出窗口,以根据特定条件显示、隐藏和更新位置。 看起来怎么样。

使用Blocker Hook 如果有任何更改,此挂钩会阻止用户导航离开

我如何在组件中使用 useCallbackPrompt

我创建了状态

showDialog
;如果用户更改当前页面/表单上的某些内容,它将更新状态
showDialog
,如果用户尝试离开,则会显示提示,并询问用户是否想要留下。

这是现场演示链接

这是 GITHUB REPO 链接

帖子

链接

3
投票

如果有任何未保存的更改(例如在未保存的表单元素中),您可以使用

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>
  );
}

0
投票

如何解决我的问题?我没有降级,而是创建了两个自定义挂钩。 useCallbackPrompt 钩子 useBlocker 钩子 useCallbackPrompt 挂钩 该挂钩处理弹出窗口,以根据特定条件显示和隐藏以及更新位置。看起来怎么样。

navigator.block 不是一个函数 [电子邮件受保护] [电子邮件受保护] [电子邮件受保护]

© www.soinside.com 2019 - 2024. All rights reserved.