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.mzph.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 …