浏览器后退按钮确认

Confirmation on browser back button

我正在尝试使用 Gatsby 实现以下目标

  1. 用户在表单页面上,如果他们点击浏览器后退按钮,将出现一个弹出窗口,询问他们是否要离开。
  2. 如果用户选择ok,那么它会返回。
  3. 如果用户选择cancel,那么它会留在这个页面

我能够通过执行以下操作“几乎”实现它

useEffect(() => {
    const confirmExit = e => {
      const leaveThisPage = window.confirm("Would you like to leave this page?")
      if (!leaveThisPage) {
        window.history.forward()
      }
    }
    window.addEventListener("popstate", confirmExit)
    return () => {
      window.removeEventListener("popstate", confirmExit)
    }
  }, [])

有一个问题,如果用户选择cancel,那么浏览器会转到上一页。然后 window.history.forward() 会发射并将它们送回。

我注意到 popstate 事件无法取消,因此 e.preventDefault() 将无法正常工作。

注意:我也尝试使用 window.onbeforeunload 进行测试,但它只会在我接近 window 时触发,或者如果我的上一个来自我的应用程序外部。我的问题有解决办法吗?

Gatsby 在后台使用 @reach/router,它不支持拦截和阻止导航(强调我的):

No history blocking. I found that the only use-case I had was preventing the user from navigating away from a half-filled out form. Not only is it pretty easy to just save the form state to session storage and bring it back when they return, but history blocking doesn’t happen when you navigate away from the app (say to another domain). This kept me from actually using history blocking and always opting to save the form state to session storage. (Source)

我支持使用 localStorage 保存表单状态的建议。