如何使用具有react-router路由转换的自定义组件?

10 javascript react-router

" 确认导航"一文解释了如何在转换钩子中使用浏览器确认框.精细.但我想使用自己的对话框.如果我使用history模块中的方法,我认为这是可能的.是否可以使用setRouteLeaveHookin react-router进行此操作?

Dan*_*olf 15

核心问题是setRouteLeaveHook期望钩子函数同步返回其结果.这意味着您没有时间显示自定义对话框组件,等待用户单击选项,然后返回结果.所以我们需要一种方法来指定一个异步钩子.这是我写的实用函数:

// Asynchronous version of `setRouteLeaveHook`.
// Instead of synchronously returning a result, the hook is expected to
// return a promise.
function setAsyncRouteLeaveHook(router, route, hook) {
  let withinHook = false
  let finalResult = undefined
  let finalResultSet = false
  router.setRouteLeaveHook(route, nextLocation => {
    withinHook = true
    if (!finalResultSet) {
      hook(nextLocation).then(result => {
        finalResult = result
        finalResultSet = true
        if (!withinHook && nextLocation) {
          // Re-schedule the navigation
          router.push(nextLocation)
        }
      })
    }
    let result = finalResultSet ? finalResult : false
    withinHook = false
    finalResult = undefined
    finalResultSet = false
    return result
  })
}
Run Code Online (Sandbox Code Playgroud)

以下是如何使用它的示例,使用vex显示一个对话框:

componentWillMount() {
  setAsyncRouteLeaveHook(this.context.router, this.props.route, this.routerWillLeave)
}
?
routerWillLeave() {
  return new Promise((resolve, reject) => {
    if (!this.state.textValue) {
      // No unsaved changes -- leave
      resolve(true)
    } else {
      // Unsaved changes -- ask for confirmation
      vex.dialog.confirm({
        message: 'There are unsaved changes. Leave anyway?' + nextLocation,
        callback: result => resolve(result)
      })
    }
  })
}
Run Code Online (Sandbox Code Playgroud)