react-activation 實現頁面保活記錄

這里寫目錄標題

    • 一、安裝插件(可選)
        • 1、react-activation (推薦)
        • 2、umi-plugin-keep-alive
    • 二、AliveScope的兩種配置方式
        • 1、在src/app.ts 中配置
        • 2、在src/layout/index.tsx中配置
    • 三、umi中的配置
    • 四、使用問題記錄
        • 1、`drop`使用不生效,使用`setTimeout`
        • 2、`refresh`在頁面mounted之前執行
    • 參考

一、安裝插件(可選)

1、react-activation (推薦)
npm install react-activation
2、umi-plugin-keep-alive

這個插件也是基于react-activation

npm install umi-plugin-keep-alive --save

使用:

import { KeepAlive } from 'umi'
const contentList = () => {return (<KeepAlive name="/About" //可按照name卸載緩存狀態下的 <KeepAlive> 節點saveScrollPosition="screen" //自動保存共享屏幕容器的滾動位置when={true} >  //true卸載時緩存,false卸載時不緩存{/*要保存狀態的組件*/}</KeepAlive>)
}

但我使用umi4搭建的項目,在安裝該插件后,umi沒有導出KeepAlive,無法使用,所以直接用的第一種

二、AliveScope的兩種配置方式

保證AliveScope穩定

1、在src/app.ts 中配置

配置文檔: https://umijs.org/docs/api/runtime-config

import React from 'react';
import { AliveScope } from 'react-activation';// 修改交給 react-dom 渲染時的根組件, 在外層包裹AliveScope
export function rootContainer(container: any) {return React.createElement(AliveScope, null, container);
}

然后在需要的組件外層包裹KeepAlive

import KeepAlive from "react-activation";
function Test() {return (<KeepAlive>{/*頁面組件*/}</KeepAlive>);
}// 如果有connect函數的可以如下寫法:
const DataMine = connect(({ user }) => ({ user }))(Mine)
export default () => <KeepAlive><DataMine/></KeepAlive>;
2、在src/layout/index.tsx中配置
export default function Layout(props: any) {return (<AliveScope>{/*頁面組件*/}</AliveScope>)
}

三、umi中的配置

umi 的 babel 配置要加在config.js文件中

  extraBabelPlugins: ['react-activation/babel']

四、使用問題記錄

1、一個組件設置keepAlive,它的某個子組件A也設置KeepAlive, 跳轉到其他頁面再跳回該頁面,A不見了

2、在某些組件不需要保活的時候,通過drop、refresh等方式去清掉某個緩存,這里要注意:

1、drop使用不生效,使用setTimeout
import { useAliveController } from 'react-activation';
const { drop, dropScope, refresh } = useAliveController();// 示例一: 要在跳轉該頁面之前執行,需要延時, 去掉setTimeout,drop不生效
drop('testName');
setTimeout(() => {history.push('/test');
}, 50);// 示例二: 在useUnactivate中使用
useUnactivate(() => {
// 在某個條件下退出要清除緩存if(xxxx) {setTimeout(() => dropScope('testName'), 0)}
})
2、refresh在頁面mounted之前執行
refresh('testName')

但這里有個小坑,refresh會重新刷新頁面,但是不會重新去拿頁面的url,也就是說如果你的某些邏輯依賴于url的query字段,需要修改一下獲取

import { useSearchParams, history } from 'umi';// 原本代碼
const Test = (props) => {const [params] = useSearchParams();// params.get('xxx') 獲取參數去處理
};// 修改為:
const Test = (props) => {const url = window.location.href;const params = (new URL(url)).searchParams;// params.get('xxx') 獲取參數去處理
};

3、滾動條的位置問題
當在兩個已經緩存的頁面跳轉時,滾動條位置是保持的,
但當從一個頁面去到一個未保活的頁面,第一次跳轉原頁面的滾動條位置未保持,第二次跳轉才保持


// KeepAlive組件增加saveScrollPosition=參數
<KeepAlive saveScrollPosition={true} />// 如果組件共享了屏幕滾動容器如 document.body 或 document.documentElement, 將 saveScrollPosition 屬性設置為 “screen”<KeepAlive saveScrollPosition="screen" />

解決方案
自定義keep.ts方法,監聽每個頁面的滾動位置,并在回到該頁面時滾回上次記錄點。

import _ from 'lodash';
import { history } from 'umi';interface PageItem {ele: Element; // 元素y: number; // 豎向位置
}
interface PageLocationProps {[key: string]: PageItem;
}
// 獲取初始的路由
let pName = history.location.pathname;// 存儲每個頁面的滾動ele和top距離
let scrollLoction: PageLocationProps = {};// 滾動記錄頁面的ele和距離
const handleScroll = _.debounce((e) => {if (!scrollLoction[pName]) {scrollLoction[pName] = {} as PageItem;}scrollLoction[pName].ele = e.target;scrollLoction[pName].y = e.target.scrollTop;},500,{ leading: false, trailing: true },
);// 路由監聽,判斷是否回滾到之前的位置
const unlisten = history.listen((route) => {pName = route.location.pathname;if (pName in scrollLoction) {// 在頁面加載出來之后,放在宏任務中即可, 時間為0也是可以的setTimeout(() => {// 如果相等,就不需要在再次scrollToif (scrollLoction[pName] && scrollLoction[pName].ele.scrollTop !== scrollLoction[pName].y) {// console.log('手動滾動', scrollLoction[pName].y);scrollLoction[pName].ele.scrollTo(0, scrollLoction[pName].y);}}, 300);}
});// 在pc端可以,在移動端發現onload,和onbeforeunload監聽都無效
// 添加監聽事件
window.addEventListener('scroll', handleScroll, true);// 卸載: 移除相關引用和監聽
window.addEventListener('beforeunload', () => {scrollLoction = {};unlisten();window.removeEventListener('scroll', handleScroll, true);
});

在app.ts中

// react-activation 從當前頁跳轉到未加載的頁面時,沒有保存位置, js修復
// 比如: 從看板詳情到指標詳情, 返回后,發現滾動位置沒有保存,但第二次進入指標詳情返回后有保存
import '@/utils/keep';

參考

react16路由緩存react-activation詳解

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73368.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73368.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73368.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

STM32使用紅外避障傳感器

1.1 介紹&#xff1a; 該傳感器模塊對環境光適應能力強&#xff0c;其具有一對紅外線發射與接收管&#xff0c;發射管發射出一定頻率的紅外線&#xff0c;當檢測方向遇到障礙物&#xff08;反射面&#xff09;時&#xff0c;紅外線反射回來被接收管接收&#xff0c;經過比較器…

python tkinter 開發蓍草占卜系統

1. 項目概述 1.1 簡介 蓍草占卜是中國傳統的占卜方法&#xff0c;用于演算六十四卦。本系統通過現代編程技術&#xff0c;將傳統的蓍草占卜方法數字化&#xff0c;提供一個準確、便捷的占卜工具。 蓍草占卜&#xff0c;作為中國古代的一種傳統占卜方法&#xff0c;承載著深厚…

Linux搭建本地時間服務器及時間同步

搭建一個本地時間服務器&#xff0c;使得局域網內主機時間保持一致。 設置正確時間 # 設置系統時間 date -s "2025-03-25 17:31:00" # 將系統時間寫入硬件時鐘 hwclock --systohc時間服務器設置 系統應該預先安裝chronyd 要允許 所有客戶端 通過你的 chronyd 服務器…

2025-3-25算法打卡

一&#xff0c;走迷宮 1.題目描述&#xff1a; 給定一個 NMNM 的網格迷宮 GG。GG 的每個格子要么是道路&#xff0c;要么是障礙物&#xff08;道路用 11 表示&#xff0c;障礙物用 00 表示&#xff09;。 已知迷宮的入口位置為 (x1,y1)(x1?,y1?)&#xff0c;出口位置為 (x…

力扣刷題39. 組合總和

39. 組合總和 - 力扣&#xff08;LeetCode&#xff09; 需要定義一個index變量用來記錄訪問數組的下標&#xff0c;每次遞歸進行傳參&#xff0c;在搜索過程中&#xff0c;因為為了避免重復數據&#xff0c;而且允許一個元素的重復出現&#xff0c;傳入index時傳入當前遍歷的i…

ISIS-3 LSDB鏈路狀態數據庫同步

上一章我們介紹了ISIS的鄰居建立關系以及ISIS的路由器角色有哪些,在不同的網絡類型當中建立鄰居關系有什么不同,并且以實驗案例抓包的形式給大家進一步介紹了建立的過程。 這一章我們來介紹ISIS中是如何實現鏈路狀態數據庫同步的,與OSPF的鏈路狀態同步有什么不同,在不同網絡類…

Opencv計算機視覺編程攻略-第三節 圖像顏色處理

第三節 圖像顏色處理 1.顏色比較2.GrabCut分割圖像3.色調、飽和度以及亮度 1.顏色比較 主要實現逐像素的顏色比較&#xff0c;其中注意BGR顏色空間不連續&#xff0c;不利于顏色提取和區分&#xff0c;轉換到Lab空間&#xff1a; int getColorDistance(const cv::Vec3b& c…

BoomCut AI 技術創建本地化的營銷視頻

目錄 視頻翻譯實驗 交換實驗 數字人實驗 核心功能與技術亮點 適用場景 BoomCut 提供用于視頻翻譯、數字人等的 AI 技術,以快速創建本地化的營銷視頻 視頻翻譯實驗 電影電影哪吒之魔童降世換成西班牙語

論華為 Pura X 折疊屏性能檢測

在科技浪潮中&#xff0c;折疊屏手機以其創新形態掀起市場熱潮。華為 Pura X 作為華為最新折疊手機&#xff0c;承載前沿科技與精湛工藝&#xff0c;成為行業焦點。它融合先進折疊屏技術與優質材質&#xff0c;致力于打破傳統手機使用邊界&#xff0c;為用戶開啟全新體驗。但產…

【藍橋杯每日一題】3.25

&#x1f3dd;?專欄&#xff1a; 【藍橋杯備篇】 &#x1f305;主頁&#xff1a; f狐o貍x “OJ超時不是終點&#xff0c;是算法在提醒你該優化時間復雜度了&#xff01;” 目錄 3.25 差分數組 一、一維差分 題目鏈接&#xff1a; 題目描述&#xff1a; 解題思路&#xff1a;…

3.25學習總結 抽象類和抽象方法+接口+內部類+API

抽象類和抽象方法&#xff1a; 有抽象方法&#xff0c;那么類肯定是抽象類。父類不一定是抽象的&#xff0c;但如果父類中有抽象方法那一定是抽象類。 如果子類中都存在吃這個行為&#xff0c;但吃的具體東西不同&#xff0c;那么吃這個行為定義在父類里面就是抽象方法&#x…

Docker 數據卷與文件掛載

Docker 數據卷與文件掛載的區別與管理指南 在 Docker 中&#xff0c;數據卷&#xff08;Volume&#xff09;和文件掛載&#xff08;Bind Mount&#xff09;是兩種常用的數據持久化方式。它們的主要目的是將容器內的數據保存到主機上&#xff0c;以便在容器重啟或刪除后數據不會…

全面系統梳理多模態LLM對齊算法

1.alignment算法發展時間軸 2.MLMM alignment結構圖 3.目前alignment策略常見的損失函數形式 4.MLLM對齊數據構造與現有數據總結

廣告推薦算法 - 學習筆記

文章目錄 1、前言2、學習筆記2.1、什么是計算廣告系統&#xff1f; 1、前言 本篇博客&#xff0c;是我用來記錄學習廣告推薦算法的一些筆記和總結。 參考內容&#xff1a; 1、王喆&#xff1a;"深度"學習計算廣告 2、deepseek 2、學習筆記 2.1、什么是計算廣告系統…

ENSP學習day10

NAT地址轉換技術&#xff08;一&#xff09; NAT&#xff08;Network Address Translation&#xff09;地址轉換技術是一種在計算機網絡中常用的技術&#xff0c;在數據包從一個網絡傳輸到另一個網絡時&#xff0c;會對數據包中的源IP地址和目的IP地址進行修改的過程。這種技術…

數據分析中,文件解析庫解析內容樣式調整

CSV文件&#xff1a;使用Python標準庫中的csv模塊&#xff0c;通過簡單的文本解析來讀取數據。 Excel文件&#xff1a;使用專門的庫&#xff08;如openpyxl、xlrd&#xff09;來解析復雜的文件格式&#xff0c;或者使用pandas庫來簡化讀取過程。 在進行文件讀取后的格式調整時…

Swift 二分法求函數的近似解

在實際開發中會遇到一些工程問題&#xff0c;需要求解復雜函數方程的問題。使用傳統的數學方法比較難以處理。本文將使用二分法不斷獲取一個函數的近似解。 二分法&#xff1a;其基本思想是利用函數在某個區間內的連續性&#xff0c;通過不斷縮小區間范圍來逼近方程的解。 算法…

stanley 路徑跟蹤控制算法

文章目錄 寫在前面的話算法思路核心代碼1 路徑發布2 獲取車子當前位置3 預瞄路徑點4 計算航向誤差5 計算橫向誤差 完整控制代碼演示視頻 寫在前面的話 軌跡跟蹤 Trajectory Tracking 和 路徑跟蹤 Path Following 是機器人控制和自動駕駛領域中的兩個核心概念&#xff0c;盡管它…

Qt中通過QLabel實時顯示圖像

Qt中的QLabel控件用于顯示文本或圖像&#xff0c;不提供用戶交互功能。以下測試代碼用于從內置攝像頭獲取圖像并實時顯示&#xff1a; Widgets_Test.h&#xff1a; class Widgets_Test : public QMainWindow {Q_OBJECTpublic:Widgets_Test(QWidget *parent nullptr);~Widgets…

在STM32F7上實現CAN總線收發隊列

下面我將提供一個完整的STM32F7 CAN總線通信實現方案&#xff0c;包含中斷驅動的收發隊列管理。 1. CAN總線配置與隊列定義 can_bus.h #ifndef __CAN_BUS_H #define __CAN_BUS_H#include "stm32f7xx_hal.h" #include "queue.h"// CAN消息結構體 typedef …