React实现路由返回拦截的三种方式

 更新时间:2024年05月31日 09:14:01   作者:内小子  
最近项目为了避免用户误操作导致数据丢失,增加返回拦截功能,但是之前由于qiankun的报错导致这个功能一直有一些问题,所以专门独立搞了一个专题研究在react中各种方式实现这个功能,需要的朋友可以参考下

背景

最近项目为了避免用户误操作导致数据丢失,增加返回拦截功能,但是之前由于qiankun的报错导致这个功能一直有一些问题,所以专门独立搞了一个专题研究在react中各种方式实现这个功能,组内小伙伴使用的是prompt方式,实现的还是比较方便,我打算探索另外别的方式实现,想用hooks的方式实现

技术栈:

  • react17
  • react-router5

方法一:使用history.block方式实现

场景:需要灵活定制弹框样式,需要比对跳转地址和当前地址

不足:还需要手动放行,并且手动实现跳转

函数有两个参数,第一个是一个对象,包含要跳转的地址等信息,第二个是触发的动作,包含三个值POP,REPLACE,PUSH,可以根据这三个类型,定制开发一些业务逻辑,函数的返回值是解除限制函数,比如只想回退拦截,手动点击跳转不拦截,就可以判断action是POP的时候返回false

实现方式如下:

 useEffect(() => {

//这里要缓存函数返回的方法,返回的函数是解除限制函数,想解除直接调用一下
    unblockRef.current = history.block((tx, action) => {
      setTargetPathname(tx.pathname)//缓存目标路径    之所以缓存,是为了弹框点击确认的时候可以获取到
      const isBlock = history.location.pathname != tx.pathname//当跳转的目标地址不是当前地址,则拦截,只要不在当前页面就拦截
      setOpen(isBlock)
      return isBlock == true ? false : true ////返回false是阻塞, 返回true是不阻塞   注意这里和block的值正好相反
    })
    return () => {
      unblockRef.current()//  组件卸载之后要解除限制
    }
  }, [history])

下面定义一个自定义的弹框,直接用原生dialog元素写个

<dialog className="dialog" open={open}>
  <p>确认离开么<br /></p>
  <button onClick={cancel}>取消</button>
  <button onClick={handleConfirm}>确定</button>
</dialog>

注意,当点击确认的时候,需要先解除限制,然后再跳转一下之前要跳转的链接,官方说有个retry的方法,我一直没有找到该方法,也可能我的react-router版本低吧

  const handleConfirm = () => {
    setOpen(false)
    if (unblockRef.current) {
      unblockRef.current();//释放限制
    }
    history.push(targetPathname)//从新跳转之前要跳转的页面
  }

方法二:使用prompt结合message函数实现自定义弹框

场景: 需要通过开关控制是否拦截,并需要自定义ui,需要比对跳转地址

不足:当点击通过的时候,如果不延时会存在状态更新不及时导致不能正常跳转

prompt接受一个when的参数,true代表拦截 message可以是一个字符串或者是一个函数,如果是字符串则调用系统默认弹框, 如果想自定义弹框则需要在函数里控制,函数返回boolean值,false代表拦截,true代表放

   <Prompt when={isBlock} message={(location) => {
     

      if (location.pathname !== history.location.pathname) {
        setTargetPathname(location.pathname)
        setIsBlock(true)
        setOpen(true)
        return false//返回false是拦截
      } else {
        setIsBlock(false)
        return true//true是放行
      }
    }}></Prompt>


当想点击确认跳转的时候,要先解除限制,然后再手动跳转,由于状态可能更新不及时,所以设置几百毫秒之后再跳转

  const handleConfirm = () => {

    setIsBlock(false)
    setOpen(false)

    //需要等待锁释放之后才能跳转
    setTimeout(() => {

      history.push(targetPathname)//从新跳转之前要跳转的页面
      console.log('确认')
    }, 100)
  }

  const cancel = () => {
    setOpen(false)
  }

方法三:基于prompt,修改路由getUserConfirmation实现自定义弹框拦截

场景:需要全局统一样式,弹框样式固定,需要灵活控制拦截条件

不足:

由于拦截弹框是在全局进行拦截,所以如果不同页面要求不同拦截弹框不太好实现

不太好判断要跳转到的地址和当前地址比对

页面中只需要写如下,通过一个开关控制是否拦截,给一个错误的提示

  <Prompt when={isBlock} message={'自定义---确定你要返回么!!!!!'}></Prompt>

然后再路由定义的时候增加如下,增加一个getUserConfirmation配置,用来获取prompt传过来的拦截消息,并缓存callback函数,这个函数用来控制是否放行

  <Router

     getUserConfirmation={(message, callback) => {
       callbackRef.current = callback
       setMessage(message)
       setOpen(true)
     }
     }
   >

当点击确认跳转则调用callback(true),点击取消则调用callback(false),路径地址就变回来了, callback(true)不需要再手动跳转,会自动跳转

  const handleConfirm = () => {
    setOpen(false)
    callbackRef.current?.(true)
  }

  const cancel = () => {
    callbackRef.current?.(false)
    setOpen(false)
  }

到此这篇关于React实现路由返回拦截的三种方式的文章就介绍到这了,更多相关React路由返回拦截内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React路由封装的实现浅析

    React路由封装的实现浅析

    路由是React项目中相当重要的概念,对于功能较为复杂的网页来说,必然会涉及到不同功能间的页面跳转,本篇文章将对React官方维护的路由库React-Router-Dom的使用和常用组件进行讲解,同时对路由组件传递param参数的方式进行讲解,希望对各位读者有所参考
    2022-08-08
  • React中实现组件通信的几种方式小结

    React中实现组件通信的几种方式小结

    在构建复杂的React应用时,组件之间的通信是至关重要的,从简单的父子组件通信到跨组件状态同步,不同组件之间的通信方式多种多样,下面我们认识react组件通信的几种方式,需要的朋友可以参考下
    2024-04-04
  • React初始化渲染过程示例详解

    React初始化渲染过程示例详解

    这篇文章主要为大家介绍了React初始化渲染过程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • react高阶组件经典应用之权限控制详解

    react高阶组件经典应用之权限控制详解

    在React中,高阶组件是重用组件逻辑的一项高级技术。下面这篇文章主要给大家介绍了关于react高阶组件经典应用之权限控制的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09
  • react router4+redux实现路由权限控制的方法

    react router4+redux实现路由权限控制的方法

    本篇文章主要介绍了react router4+redux实现路由权限控制的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • React 中的重新渲染类组件及函数组件

    React 中的重新渲染类组件及函数组件

    这篇文章主要为大家介绍了React 中的重新渲染类组件及函数组件使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • React使用api的方式封装弹窗的示例代码

    React使用api的方式封装弹窗的示例代码

    在现代开发中的弹窗样式,经常会是底部一个叉号样式的弹窗,但是目前组件库中并无类似弹窗组件,本文小编给大家介绍了React使用api的方式封装弹窗的示例,感兴趣的小伙伴跟着小编一起来看看吧
    2024-09-09
  • 浅谈React前后端同构防止重复渲染

    浅谈React前后端同构防止重复渲染

    这篇文章主要介绍了浅谈React前后端同构防止重复渲染,首先解释React前后端同构、React首屏渲染的概念。然后通过这2个概念解决服务端渲染完成后浏览器端重复渲染的问题。有兴趣的可以了解一下
    2018-01-01
  • react-three/postprocessing库的参数中文含义使用解析

    react-three/postprocessing库的参数中文含义使用解析

    这篇文章主要介绍了react-three/postprocessing库的参数中文含义使用总结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • React实现生成和导出Word文档的方法详解

    React实现生成和导出Word文档的方法详解

    React是一个流行的JavaScript库,用于构建现代前端应用程序,本文将深入探讨如何在React中生成和导出Word文档,感兴趣的小伙伴可以学习一下
    2023-09-09

最新评论