How to use a custom component with react-router route transitions?

前端 未结 5 1549
生来不讨喜
生来不讨喜 2021-02-08 11:25

The article Confirming Navigation explains how to use a browser confirmation box in your transition hook. Fine. But I want to use my own Dialog box. If I were to use the methods

5条回答
  •  独厮守ぢ
    2021-02-08 11:49

    The core problem is that setRouteLeaveHook expects the hook function to return its result synchronously. This means you don't have the time to display a custom dialog component, wait for the user to click an option, and then return the result. So we need a way to specify an asynchronous hook. Here's a utility function I wrote:

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

    Here is an example of how to use it, using vex to show a dialog box:

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

提交回复
热议问题