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

时间:2019-04-03 01:48:41

标签: javascript reactjs jsx mobx

我有类似这样的东西:

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确实可以执行某些操作。我不知道要使用什么标准,只是,它应该在以下情况下触发确认窗口:

  • 用户更改了URL并尝试导航
  • 用户点击链接
  • 用户刷新浏览器

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

1 个答案:

答案 0 :(得分:1)

当一种情况发生时,您无需想出一种“检测”方法。

  
      
  • 用户更改了URL并尝试导航
  •   
  • 用户刷新浏览器
  •   

已经通过为onbeforeunload分配回调来处理这些问题。

  
      
  • 用户点击链接
  •   

如果您正在使用Prompt处理导航,这已经通过渲染react-router来解决。

因此,

props.navigatingAway最好命名为props.shouldPreventNavigation或类似的名称,因为它应该发出信号:如果您应该阻止导航,而不是您是否正在导航。

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

From the docs for Prompt:

  

您可以始终渲染它,而无需传递条件<Prompt>when={true}来阻止或允许相应地导航,而不是有条件地在守卫后面渲染when={false}

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

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

如果Prompt开箱时when={true}不能正常工作,则可能是react-router没有正确管理您的路由。

请注意,例如,如果window.onbeforeunload在分配了回调的情况下卸载了,请确保考虑使用ConfirmationDialog会发生什么。使用适当的生命周期方法进行管理,否则在测试时会变得很奇怪。