显示自定义对话框setRouteLeaveHook或history.listenBefore react-router / redux?

时间:2016-03-03 11:04:27

标签: reactjs react-router redux

我似乎无法弄清楚如何展示自定义对话,而不是使用window.confirmrouteWillLeave使用的普通history.listenBefore。基本上我已经建立了一个通知系统并检查表单是否脏({1}}

如果表单是脏的,则表示用户有未保存的更改。如果他们改变路线,我想显示我的通知,其中有两个按钮const { dispatch, history, dirty } = this.props;STAY,它们都可以使用onClick处理程序。

我花了一些时间用谷歌搜索,并没有提到我如何使用IGNORE完成此任务。我能找到的最接近的事情就是使用routeWillLeave然而有文档说我需要这样做。

history.listenBefore

但我正在使用来自react-router的browserHistory来启动我的商店let history = createHistory({ getUserConfirmation(message, callback) { callback(window.confirm(message)) // The default behavior } })

如何在点击链接后停止路线更改,使用我的自定义通知系统显示通知,并根据点击哪个按钮转换到新路线或停留?

以下是我的通知系统如何工作的示例以及我前进的方向明显无效,因为所有这些都是默认情况下在window.confirm对话框中显示的字符串。

const history = syncHistoryWithStore(browserHistory, store);

由于

1 个答案:

答案 0 :(得分:0)

我决定使用的另一个解决方案是在正常的setRouterLeaveHook回调中返回false,然后显示我的对话框并使用传递给回调的nextLocation来根据按钮选择推送下一个路由。

router.setRouteLeaveHook(route, this.routerWillLeave.bind(this));

routerWillLeave(nextLocation){
  let { dirty, dispatch, resetForm } = this.props;
  if (dirty) {
    let dialog = {
      id: Date.now(),
      showTitle: true,
      titleContent: 'Unsaved Changes',
      titleIcon: 'fa fa-warning',
      content: <span>You have <strong>unsaved</strong> changes! <strong>Discard</strong> them?</span>,
      type: 'confirm',
      handleCloseClick: (e) => {
        e.preventDefault();
        dispatch(closeDialog());
      },
      acceptBtn: {
        title: 'Okay',
        handler: (e) => {
          e.preventDefault();
          resetForm();
          // Wait for call stack to unwind and then execute
          // the following which will now have the updated values.
          setTimeout(() => {
            dispatch(push(nextLocation));
            dispatch(closeDialog());
          }, 0);
        }
      },
      denyBtn: {
        title: 'Deny',
        handler: (e) => {
          e.preventDefault();
          dispatch(closeDialog());
        }
      }
    }
    dispatch(addDialogWindow(dialog));
    dispatch(openDialog(false, (e) => dispatch(closeDialog()), false));
    return false;
  }
  return true;
}