React & MobX - 用户离开现有页面时的确认对话框

React & MobX - Confirmation dialog when a user navigates away from the existing page

我有一些看起来像这样的东西:

import React from 'react';
import PropTypes from 'prop-types';
import { Prompt } from 'react-router-dom';

const ConfirmationDialog = (props) => {
  if (props.navigatingAway) {
    window.onbeforeunload = () => true;
  } else {
    window.onbeforeunload = null;
  }
  return (
    <Prompt
      when={props.navigatingAway}
      message="Are you sure?"
    />
  );
};

ConfirmationDialog.propTypes = {
  navigatingAway: PropTypes.bool.isRequired,
};

export default ConfirmationDialog;

我正在尝试找出扩展它的最佳方法,以便 navigatingAway 真正发挥作用。我不明白使用什么标准,必然,只是它应该触发确认 window when:

检查 when 的 URL 更改的最佳方法是什么?

您不需要想出一种方法来 'detect' 当您的某个场景正在发生时。

  • a user changes the URL and attempts to navigate away
  • a user refreshes the browser

这些已经通过向 onbeforeunload 分配回调来处理。

  • a user clicks on a link

如果您使用 react-router 处理导航,这已经通过呈现 Prompt 来处理。

props.navigatingAway,然后,最好命名为 props.shouldPreventNavigation 或类似的名称,因为它应该表示您是否应该阻止导航,而不是您是否正在导航。

例如,如果您总是希望在挂载 ConfirmationDialog 时在导航之前出现提示,那么 props.shouldPreventNavigation 应该始终为真,您就完成了。如果表单中有未保存的数据,一个常见的用例是将其设置为 true。

From the docs for Prompt:

Instead of conditionally rendering a <Prompt> behind a guard, you can always render it but pass when={true} or when={false} to prevent or allow navigation accordingly.

为了说明这一点,以下两个片段在功能上是等效的,除了性能等:

render() {
    return (
        <Prompt
            when={this.props.navigatingAway}
            message="Are you sure?"
        />
    )
}
render() {
    if (this.props.navigatingAway) {
        return (
            <Prompt
                when={true}
                message="Are you sure?"
            />
        )
    }
    return null;
}

如果 Promptwhen={true} 时无法正常工作,则可能是 react-router.[=32 未正确管理您的路由=]

作为旁注,请务必考虑 window.onbeforeunload 会发生什么情况,例如,如果您的 ConfirmationDialog 在分配了回调时卸载。使用适当的生命周期方法来管理它,否则当你测试它时事情会变得很奇怪。