react-router v4:使用自定义挂钩而不是提示阻止转换

时间:2017-03-30 15:28:44

标签: javascript react-router history.js html5-history

react-router v3中,我一直在使用router.setRouteLeaveHook检查表单是否有未保存的更改,如果是,则返回false以阻止转换。然后我会显示一个带有3个按钮的自定义引导模式对话框:保存更改,放弃更改,并保留在此处。

我无法使用react-router v4的Prompt组件来执行此操作,因为无法自定义浏览器确认对话框中显示的按钮。看起来他们已经摆脱了取消转换的任何方式,只允许您在浏览器确认对话框中要求用户批准转换。

我尝试查看Promptit just passes the dialog message to history的代码,这样就不会让我知道如何设置v3风格的路由离开。

是否有可能或者react-router开发者是否因为某些原因故意决定删除此功能?

3 个答案:

答案 0 :(得分:3)

根据the history package docs,您可以将window.confirm替换为您喜欢的任何内容:

  

默认情况下,window.confirm用于向用户显示提示消息。如果您需要覆盖此行为(或者如果您正在使用不承担DOM环境的createMemoryHistory),请在创建历史记录对象时提供getUserConfirmation函数。

因此,如果你想使用你自己的对话框,这样的事情应该会让你看到:

const history = createHistory({
  getUserConfirmation(message, callback) {
    showMyCustomDialog(message)
      .then(result => callback(result === 'The YES button'))
  }
})

这意味着您为整个会话设置的getUserConfirmation消息都可以设置,但您可以将其抽象到导航阻止层,该层保存对话框的其他详细信息,例如:标题,按钮文字,颜色等。

或者,您可以劫持message参数并将其用于对话框配置,尽管这可能闻起来有点讨厌。但它并不是一个完美的系统,所以你所做的任何事都可能是一个黑客攻击。

React Router v4允许您在创建路由器时通过此方法(请参阅here):

<BrowserRouter getUserConfirmation={yourConfirmationFunction} />

答案 1 :(得分:1)

可以使用 Prompt 来显示自定义对话。信用和详细解释here

Prompt 需要一个消息道具,这里我们可以使用自定义函数进行对话,它应该返回 false 以防止导航。

const BlockingPage = () => {
  const [block, setBlock] = useState(true);
  
  const blockedNavigation = (nLocation) => {
    //nLocation gives the next location object
    
    /**
      * Your custom logic
      *
    **/
    
    //required to block navigation
    return false
  } 

  return(
    <div>
      <Prompt when={block} message={blockedNavigation}/>
    </div>
  )

} 

答案 2 :(得分:0)

我不认为这是可能的。 react-router-v4使用名为history的包,它又使用HTML5历史API。历史api只会在你点击后退按钮(onpopstate)时通知你,如果你仔细想想这很有意义,因为你不想让网站不让你在页面之间移动。

您可以做的最好的事情是window onbeforeunload event,它会向您询问用户确认的提示,但这正是您所使用的反应路由器所暴露的内容。

您可以通过猴子修补react-router的内部历史记录对象获得您想要的一些功能,这样您就可以添加自己的行为。但有一点需要注意,只有当你对路由器的 import numpy as np def gaussian(x, mu, sigma): g = (1./ (sigma * np.sqrt(2*np.pi))) * np.exp(-(x - mu)**2 / sigma**2) return g values = [10, 100, 100]; gauss_I = gaussian( values, np.mean(values), np.std(values) ) print(np.convolve( values, gauss_I)); 组件和朋友做出反应时才会起作用,所以你将无法拦截刷新和其他你想要的东西。

如果你想走那条路,请告诉我,我可以给你一些见解或代码示例,说明这项工作的效果如何,我会更新我的答案。