最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React實(shí)現(xiàn)路由返回?cái)r截的三種方式

 更新時(shí)間:2024年05月31日 09:14:01   作者:內(nèi)小子  
最近項(xiàng)目為了避免用戶誤操作導(dǎo)致數(shù)據(jù)丟失,增加返回?cái)r截功能,但是之前由于qiankun的報(bào)錯(cuò)導(dǎo)致這個(gè)功能一直有一些問題,所以專門獨(dú)立搞了一個(gè)專題研究在react中各種方式實(shí)現(xiàn)這個(gè)功能,需要的朋友可以參考下

背景

最近項(xiàng)目為了避免用戶誤操作導(dǎo)致數(shù)據(jù)丟失,增加返回?cái)r截功能,但是之前由于qiankun的報(bào)錯(cuò)導(dǎo)致這個(gè)功能一直有一些問題,所以專門獨(dú)立搞了一個(gè)專題研究在react中各種方式實(shí)現(xiàn)這個(gè)功能,組內(nèi)小伙伴使用的是prompt方式,實(shí)現(xiàn)的還是比較方便,我打算探索另外別的方式實(shí)現(xiàn),想用hooks的方式實(shí)現(xiàn)

技術(shù)棧:

  • react17
  • react-router5

方法一:使用history.block方式實(shí)現(xiàn)

場景:需要靈活定制彈框樣式,需要比對跳轉(zhuǎn)地址和當(dāng)前地址

不足:還需要手動(dòng)放行,并且手動(dòng)實(shí)現(xiàn)跳轉(zhuǎn)

函數(shù)有兩個(gè)參數(shù),第一個(gè)是一個(gè)對象,包含要跳轉(zhuǎn)的地址等信息,第二個(gè)是觸發(fā)的動(dòng)作,包含三個(gè)值POP,REPLACE,PUSH,可以根據(jù)這三個(gè)類型,定制開發(fā)一些業(yè)務(wù)邏輯,函數(shù)的返回值是解除限制函數(shù),比如只想回退攔截,手動(dòng)點(diǎn)擊跳轉(zhuǎn)不攔截,就可以判斷action是POP的時(shí)候返回false

實(shí)現(xiàn)方式如下:

 useEffect(() => {

//這里要緩存函數(shù)返回的方法,返回的函數(shù)是解除限制函數(shù),想解除直接調(diào)用一下
    unblockRef.current = history.block((tx, action) => {
      setTargetPathname(tx.pathname)//緩存目標(biāo)路徑    之所以緩存,是為了彈框點(diǎn)擊確認(rèn)的時(shí)候可以獲取到
      const isBlock = history.location.pathname != tx.pathname//當(dāng)跳轉(zhuǎn)的目標(biāo)地址不是當(dāng)前地址,則攔截,只要不在當(dāng)前頁面就攔截
      setOpen(isBlock)
      return isBlock == true ? false : true ////返回false是阻塞, 返回true是不阻塞   注意這里和block的值正好相反
    })
    return () => {
      unblockRef.current()//  組件卸載之后要解除限制
    }
  }, [history])

下面定義一個(gè)自定義的彈框,直接用原生dialog元素寫個(gè)

<dialog className="dialog" open={open}>
  <p>確認(rèn)離開么<br /></p>
  <button onClick={cancel}>取消</button>
  <button onClick={handleConfirm}>確定</button>
</dialog>

注意,當(dāng)點(diǎn)擊確認(rèn)的時(shí)候,需要先解除限制,然后再跳轉(zhuǎn)一下之前要跳轉(zhuǎn)的鏈接,官方說有個(gè)retry的方法,我一直沒有找到該方法,也可能我的react-router版本低吧

  const handleConfirm = () => {
    setOpen(false)
    if (unblockRef.current) {
      unblockRef.current();//釋放限制
    }
    history.push(targetPathname)//從新跳轉(zhuǎn)之前要跳轉(zhuǎn)的頁面
  }

方法二:使用prompt結(jié)合message函數(shù)實(shí)現(xiàn)自定義彈框

場景: 需要通過開關(guān)控制是否攔截,并需要自定義ui,需要比對跳轉(zhuǎn)地址

不足:當(dāng)點(diǎn)擊通過的時(shí)候,如果不延時(shí)會(huì)存在狀態(tài)更新不及時(shí)導(dǎo)致不能正常跳轉(zhuǎn)

prompt接受一個(gè)when的參數(shù),true代表攔截 message可以是一個(gè)字符串或者是一個(gè)函數(shù),如果是字符串則調(diào)用系統(tǒng)默認(rèn)彈框, 如果想自定義彈框則需要在函數(shù)里控制,函數(shù)返回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>


當(dāng)想點(diǎn)擊確認(rèn)跳轉(zhuǎn)的時(shí)候,要先解除限制,然后再手動(dòng)跳轉(zhuǎn),由于狀態(tài)可能更新不及時(shí),所以設(shè)置幾百毫秒之后再跳轉(zhuǎn)

  const handleConfirm = () => {

    setIsBlock(false)
    setOpen(false)

    //需要等待鎖釋放之后才能跳轉(zhuǎn)
    setTimeout(() => {

      history.push(targetPathname)//從新跳轉(zhuǎn)之前要跳轉(zhuǎn)的頁面
      console.log('確認(rèn)')
    }, 100)
  }

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

方法三:基于prompt,修改路由getUserConfirmation實(shí)現(xiàn)自定義彈框攔截

場景:需要全局統(tǒng)一樣式,彈框樣式固定,需要靈活控制攔截條件

不足:

由于攔截彈框是在全局進(jìn)行攔截,所以如果不同頁面要求不同攔截彈框不太好實(shí)現(xiàn)

不太好判斷要跳轉(zhuǎn)到的地址和當(dāng)前地址比對

頁面中只需要寫如下,通過一個(gè)開關(guān)控制是否攔截,給一個(gè)錯(cuò)誤的提示

  <Prompt when={isBlock} message={'自定義---確定你要返回么?。。。?!'}></Prompt>

然后再路由定義的時(shí)候增加如下,增加一個(gè)getUserConfirmation配置,用來獲取prompt傳過來的攔截消息,并緩存callback函數(shù),這個(gè)函數(shù)用來控制是否放行

  <Router

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

當(dāng)點(diǎn)擊確認(rèn)跳轉(zhuǎn)則調(diào)用callback(true),點(diǎn)擊取消則調(diào)用callback(false),路徑地址就變回來了, callback(true)不需要再手動(dòng)跳轉(zhuǎn),會(huì)自動(dòng)跳轉(zhuǎn)

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

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

到此這篇關(guān)于React實(shí)現(xiàn)路由返回?cái)r截的三種方式的文章就介紹到這了,更多相關(guān)React路由返回?cái)r截內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • ReactiveCocoa代碼實(shí)踐之-UI組件的RAC信號(hào)操作

    ReactiveCocoa代碼實(shí)踐之-UI組件的RAC信號(hào)操作

    這篇文章主要介紹了ReactiveCocoa代碼實(shí)踐之-UI組件的RAC信號(hào)操作 的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • react native帶索引的城市列表組件的實(shí)例代碼

    react native帶索引的城市列表組件的實(shí)例代碼

    本篇文章主要介紹了react-native城市列表組件的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • React?Native實(shí)際項(xiàng)目中的經(jīng)驗(yàn)和踩坑記錄

    React?Native實(shí)際項(xiàng)目中的經(jīng)驗(yàn)和踩坑記錄

    在當(dāng)今移動(dòng)應(yīng)用開發(fā)的浪潮中,React Native以其跨平臺(tái)、高效開發(fā)的特點(diǎn)脫穎而出,成為眾多開發(fā)者首選的框架之一,這篇文章主要介紹了React Native實(shí)際項(xiàng)目中的經(jīng)驗(yàn)和踩坑記錄的相關(guān)資料,需要的朋友可以參考下
    2026-03-03
  • react 組件傳值的三種方法

    react 組件傳值的三種方法

    這篇文章主要介紹了react 組件傳值的三種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • react顯示文件上傳進(jìn)度的示例

    react顯示文件上傳進(jìn)度的示例

    這篇文章主要介紹了react顯示文件上傳進(jìn)度的示例,幫助大家更好的理解和學(xué)習(xí)使用react,感興趣的朋友可以了解下
    2021-04-04
  • react使用.env文件管理全局變量的方法

    react使用.env文件管理全局變量的方法

    本文主要介紹了react使用.env文件管理全局變量的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • react-native-tab-navigator組件的基本使用示例代碼

    react-native-tab-navigator組件的基本使用示例代碼

    本篇文章主要介紹了react-native-tab-navigator組件的基本使用示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-09-09
  • React組件的三種寫法總結(jié)

    React組件的三種寫法總結(jié)

    本文主要總結(jié)了React組件的三種寫法以及最佳實(shí)踐,具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • Remix后臺(tái)開發(fā)之remix-antd-admin配置過程

    Remix后臺(tái)開發(fā)之remix-antd-admin配置過程

    這篇文章主要為大家介紹了Remix后臺(tái)開發(fā)之remix-antd-admin配置過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • react實(shí)現(xiàn)阻止父容器滾動(dòng)

    react實(shí)現(xiàn)阻止父容器滾動(dòng)

    這篇文章主要介紹了react實(shí)現(xiàn)阻止父容器滾動(dòng)方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11

最新評(píng)論

陵川县| 彭阳县| 晋江市| 巨野县| 岳池县| 铜鼓县| 南部县| 会宁县| 湟中县| 莱芜市| 融水| 那坡县| 萨迦县| 靖江市| 安义县| 荣昌县| 常宁市| 油尖旺区| 大冶市| 阳城县| 海宁市| 佛山市| 宣城市| 咸丰县| 渭南市| 荔波县| 宝兴县| 新乡市| 龙岩市| 芷江| 巴马| 越西县| 盈江县| 阿巴嘎旗| 孟津县| 贡嘎县| 金湖县| 鹤峰县| 大厂| 马山县| 乳山市|