react-router-dom 路由拦截-复制可用

675 阅读1分钟

react路由拦截

tnnd,我觉得这种场景还挺常见的,进入详情,一旦修改了之后要跳转给个弹窗提示,没有保存是不是要强制返回,也就是路由拦截

问题

本来哥们没什么问题,项目用的Prompt是好用的,但是项目被拆分用微应用的方式,就nnd不好用了,不知道是版本问题还是微应用加载问题,我也懒得排查,我知道v6删除了Prompt,所以肯定有不用这个的方式来拦截路由的

解决

查了半天用history.block拦截,抄了个钩子,不好使,给哥们气闷了,想了半天,return false就好了

import { useEffect } from 'react'
import { useHistory } from 'react-router-dom'

export default (blocker, when)=>{
  const history = useHistory();

  useEffect(()=>{
    if(!when) return
    // 防止关闭tab时候弹窗,也可以不用
    window.addEventListener('beforeunload', removeBeforeUnload)
    const unblock = history.block(tx=>{

      const autoUnblockingTx = {
        ...tx,
        retry() {
          unblock()
          // tnnd v5版本好像没有retry, 留着v6用
          tx.retry?.()
        },
      }
      blocker(autoUnblockingTx)
      return false
    })

    function removeBeforeUnload() {
      unblock()
    }
    return () => {
      unblock()
      window.removeEventListener('beforeunload', removeBeforeUnload)
    }
  }, [ when ])
}
  useBlock(tx=>{
    // 打开自定义弹窗
    setPromptVis(true)
    // 把要跳转的路径存起来,备用
    setLocation(tx.pathname)
  }, when)

用到直接复制,我不像有的人给代码就给一半,md跑不起来