react 实现页面状态缓存(keep-alive)

前言:

因为 react、vue都是单页面应用,路由跳转时,就会销毁上一个页面的组件。但是有些项目不想被销毁,想保存状态。

比如:h5项目跳转其他页面返回时,页面状态不丢失。设想一个 页面我滑倒了中间,然后跳转到 详情页然后 返回,之前的页面刷新了,回到顶部了肯定不行(搜索条件之类的消失了,滚动条回到顶部了)!

比如:pc端项目后台管理项目里点击时 打开一个页签,页签切换,状态页会丢失。每次切换页签都重新请求了接口。

解决方案:

方案调研:

经过我的调研:
我找到的 第三放库有:
react-activation
umi-plugin-keep-alive
umi-plugin-keep-alive-tabs
react-keepalive-router
react-router-cache-route

redux、dva等(状态共享插件)

react-keepalive-router、react-router-cache-route:

react-keepalive-router、react-router-cache-route 是个人开发的,github上issues里的建议也没及时回答。所以我就放弃了,没考虑。

Offscreen:

Offscreen是react 18.x出的实验性api,所以我也放弃了。可以看react Offscreen
不过 此api如果正式使用的话,应该是最好的选择。其原理就是 把页面 隐藏起来,不销毁组件树。其实其他 插件原理也是这样。

在这里插入图片描述

umi-plugin-keep-alive、umi-plugin-keep-alive-tabs:

umi-plugin-keep-alive、umi-plugin-keep-alive-tabs 是umi里的,是阿里开发的,优先考虑的就是这个,但看了 文档发现 它基于 react-activation。而且 作者也让关注 。
npm umi-plugin-keep-alive

umi-plugin-keep-alive api
其实 如果你项目是 umi的话 用 umi-plugin-keep-alive也可以(低版本umi可能不行)。antd-pro
若依等等基于umi搭建的库都可以使用umi-plugin-keep-alive。这个插件 和umi绑定,所以我也放弃了,但应该也可以单独使用(我没试过)。

redux等状态共享插件,需要项目搭建时就使用,原理就是,页面里不写 useState和state全都放到 store里。然后对整个store缓存。每次进入页面 判断一下有缓存就走缓存,没有重新请求。像redux之类的都有持久化插件,配合持久化插件就很容易实现。缺点是繁琐,且破坏了 不优雅,页面里不能写状态。而且 还要额外 记录滚动条的位置。

react-activation:

所以综上我选择了 react-activation 它是路由级别的缓存。
在这里插入图片描述

react-activation基础使用步骤及配置:

React Activation 仅支持 React 16 及以上版本

注意
1.请勿使用 <React.StrictMode />
2.(React v18+)不要使用 ReactDOMClient.createRoot ,使用 ReactDOM.render 代替, https://github.com/CJY0208/react-activation/issues/225#issuecomment-1311136388

在这里插入图片描述

1.安装 react-activation

yarn add react-activation
# or
npm install react-activation

(可选,推荐)在 .babelrc 中添加 react-activation/babel 插件
该插件在编译过程中为每个JSX元素添加了一个 _nk 属性,以帮助 react-activation 运行时根据 react-node-key 的渲染位置生成唯一的标识符。

{"plugins": ["react-activation/babel"]
}

如果不想使用Babel,建议每个 声明一个全局唯一不变的 cacheKey 属性,以保证该高速缓存的稳定性,如下所示:

<KeepAlive cacheKey="UNIQUE_ID" />

2.import KeepAlive 然后包裹要缓存的组件 或者元素。

官网示例:

// App.jsimport React, { useState } from 'react'
import KeepAlive from 'react-activation'function Counter() {const [count, setCount] = useState(0)return (<div><p>count: {count}</p><button onClick={() => setCount(count => count + 1)}>Add</button></div>)
}function App() {const [show, setShow] = useState(true)return (<div><button onClick={() => setShow(show => !show)}>Toggle</button>{show && (<KeepAlive><Counter /></KeepAlive>)}</div>)
}export default App

3.将 外层放置在不会卸载的位置,通常在应用入口处

配合路由使用react-activation

1.isCache是自定义的属性,用来标识是否 缓存。true就是改路由需要缓存。

  {path: "/",component: <Initial />,title: "主页",name: "initPage",isCache: true,cacheKey: "home",}

路由配置可以参考:
react create-react-app v5 配置路由(报错及注意事项)
App.js 入口文件 或者 路由配置页面里 封装一层 根据 isCache值来确定是否使用 keepAlive包裹。如下:

import React from "react";
import { BrowserRouter, Routes, Route, HashRouter } from "react-router-dom";
import routes from "./routes.js";
import KeepAlive from "react-activation";
// 封装一层 专门负责显示页面标题
const DomTitle = ({ route }) => {const { title, component, isCache ,cacheKey,name} = route;document.title = title;if (isCache) {return <KeepAlive cacheKey={cacheKey} name={name}>{component}</KeepAlive>;}return <>{component}</>;
};
const App = () => {return (<HashRouter><Routes>{routes.map((route) => (<Routekey={route.path}path={route.path}//element={route.component   }// 专门负责显示页面标题element={<DomTitle route={route} />}/>))}</Routes></HashRouter>);
};

还可以手动清除缓存

import {useActivate,useUnactivate,withActivation,withAliveScope,useAliveController,
} from "react-activation";const { drop, dropScope, clear, getCachingNodes } = useAliveController();console.log(getCachingNodes(), "缓存节点");//drop("homePage"); // 手动关闭某个页面// dropScope("detailPage");dropScope("homePage");  // 参数就是上面定义的  cacheKey

还需要 将 外层放置在不会卸载的位置,通常在应用入口处我的项目时create-react-app 是index.js。
index.js

具体 api使用方法和注意事项请看:
具体api可以看(如果 github打不开可以看npm的,npm是英文的,可以用edge浏览器 翻译一下):
react-activation github 使用文档
react-activation npm 使用文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/641131.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

仓储管理系统——软件工程报告(需求分析)②

需求分析 一、系统概况 仓库管理系统是一种基于互联网对实际仓库的管理平台&#xff0c;旨在提供一个方便、快捷、安全的存取货物和查询商品信息平台。该系统通过在线用户登录查询&#xff0c;可以线上操作线下具体出/入库操作、查询仓库商品信息、提高仓库运作效率&#xff…

shell脚本概述

将命令写到脚本里面&#xff0c;利用路径或者解释器去执行。简要来说脚本其实就是命令的集合。 例如&#xff1a;echo $&#xff1f; 自定义变量&#xff0c;查看上次命令执行是否正确 linux常用的shell 脚本的构成&#xff1a; 1.解释器 &#xff08;脚本是用什么语言写的…

10个常用python自动化脚本

大家好&#xff0c;Python凭借其简单和通用性&#xff0c;能够为解决每天重复同样的工作提供最佳方案。本文将探索10个Python脚本&#xff0c;这些脚本可以帮助自动化完成任务&#xff0c;提高工作效率。无论是开发者、数据分析师还是仅仅想简化工作流程的普通用户&#xff0c;…

【数据结构】二叉树算法讲解(定义+算法原理+源码)

博主介绍&#xff1a;✌全网粉丝喜爱、前后端领域优质创作者、本质互联网精神、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战✌有需要可以联系作者我哦&#xff01; &#x1f345;附上相关C语言版源码讲解&#x1f345; &#x1f44…

Java - 深入四大限流算法:原理、实现与应用

文章目录 Pre概述简单计数器原理实现测试优缺点 滑动窗口算法原理实现测试优缺点 漏桶算法原理实现测试优缺点 令牌桶算法原理实现测试优缺点 小结 Pre 深入理解分布式技术 - 限流 并发编程-25 高并发处理手段之消息队列思路 应用拆分思路 应用限流思路 SpringBoot - 优雅…

画眉(京东科技设计稿转代码平台)介绍

前言 随着金融App业务的不断发展&#xff0c;为了满足不同场景下的用户体验及丰富的业务诉求&#xff0c;业务产品层面最直接体现就是大量新功能的上线及老业务的升级&#xff0c;随之也给研发带来了巨大的压力&#xff0c;所以研发效率的提升就是当前亟需解决的问题&#xff…

QGIS生成热力图

目录 1 QGIS介绍 2 实现效果 3 具体步骤 3.1 获取北京市地图&#xff08;区县级&#xff09; 3.1.1 方法一&#xff1a;直接找到北京市地图 3.1.2 方法二&#xff1a;若没有单独的北京市地图&#xff0c;从中国地图上提取 3.2 获取数据 3.3 导入数据 1 QGIS介绍…

1148. 秘密的牛奶运输 (次小生成树)

1148. 秘密的牛奶运输 - AcWing题库 农夫约翰要把他的牛奶运输到各个销售点。 运输过程中&#xff0c;可以先把牛奶运输到一些销售点&#xff0c;再由这些销售点分别运输到其他销售点。 运输的总距离越小&#xff0c;运输的成本也就越低。 低成本的运输是农夫约翰所希望的。…

知识笔记(九十六)———在vue中使用echarts

1、安装 npm install echarts --save 2、在vue中引入&#xff08;全局引入&#xff09; // 引入echarts import echarts from echarts Vue.prototype.$echarts echarts3、在vue中的使用 需要用到echart的地方先设置一个div的id、宽高 提示&#xff1a; 可以在一个页面中引…

数据结构之使用顺序表写出通讯录

前言 昨天我们踏入了数据结构的深山&#xff0c;并且和顺序表battle了一番&#xff0c;虽说最后赢了&#xff0c;但同时也留下了一个问题&#xff1a;如何从顺序表的增删查改加强到通讯录的的增删查改&#xff0c;别急&#xff0c;今天就带你一探究竟。 一.回顾与思考 我们昨…

geemap学习笔记053:纹理特征

前言 纹理特征通常描述了遥感影像中像素之间的空间关系和变化&#xff0c;对于地物分类、目标检测以及图像分割等遥感应用非常有价值。本节将会介绍Earth Engine中提供的一些纹理特征计算方法&#xff0c;包括熵和灰度共生矩阵。 1 导入库并显示数据 import ee import geema…

【UE5】第一次尝试项目转插件(Plugin)的时候,无法编译

VS显示100条左右的错误&#xff0c;UE热编译也不能通过。原因可能是[名字.Build.cs]文件的错误&#xff0c;缺少一些内容&#xff0c;比如说如果要写UserWidget类&#xff0c;那么就要在 ]名字.Build.cs] 中加入如下内容&#xff1a; public class beibaoxitong : ModuleRules …

自己本机Video retalking制作数字人

首先需要注意的是&#xff0c;这个要求你的笔记本显存和内存都比较大。我的电脑内存是64G&#xff0c;显卡是8G&#xff0c;操作系统是Windows 11&#xff0c;勉强能够运行出来&#xff0c;但是效果不是很好。 效果如下&#xff0c;无法上传视频&#xff0c;只能通过图片展示出…

[分章:阅读]《我的第一本算法书》

第一章数据结构 1.链表 1、数据结构之一&#xff0c;线性排列数据&#xff0c;指针链接数据&#xff1b;访问O&#xff08;n&#xff09;&#xff0c;删除/添加O&#xff08;1&#xff09; 2、类似链条。 2.数组 1、线性排列数据&#xff0c;含数据下标&#xff08;即索引&…

C++如何在0和1之间取随机数

在C中&#xff0c;你可以使用 <random> 库来生成0和1之间的随机数。这个库提供了各种生成随机数的方法&#xff0c;包括均匀分布的随机数。 下面是一个简单的例子&#xff0c;展示如何使用 <random> 库来生成0和1之间的随机数&#xff1a; cpp复制代码 #include…

二、docker的常用命令(持续补充img)

目录 一、启动相关1.设置容器开机启动 二、查询相关1.查询所有容器&#xff08;包括停止的&#xff09; 三、修改相关1.指定容器开机自启动 一、启动相关 1.设置容器开机启动 在我们使用镜像run一个容器的时候&#xff0c;希望这个容器随着docker的启动而启动&#xff08;我的…

Ubuntu20.04.3LTS桌面版与Window10双系统并存

Ubuntu20.04.3LTS桌面版与Window10双系统并存 文章目录 Ubuntu20.04.3LTS桌面版与Window10双系统并存1.分区与安装1. 硬盘分区1. 一般用途2. 服务器用 2. 操作系统版本及分区信息3. 安装时创建用户4. 安装后修改root设置用户密码&#xff1a;3. 安装时指定ip4. 设置静态IP 2. 安…

【leetcode100-051到054】【图论】四题合集

【岛屿数量】 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外&#xff0c;你可以假设…

Java线程池七大参数详解和配置(面试重点)

一、corePoolSize核心线程数 二、maximunPoolSize最大线程数 三、keepAliveTime空闲线程存活时间 四、unit空闲线程存活时间的单位 五、workQueue线程工作队列 1、ArrayBlockingQueue FIFO有界阻塞队列 2、LinkedBlockingQueue FIFO无限队列 3、PriorityBlockingQueue V…

【代码随想录】刷题笔记Day54

前言 差单调栈就结束代码随想录一刷啦&#xff0c;回家二刷打算改用python补充进博客&#xff0c;小涛加油&#xff01;&#xff01;&#xff01; 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; 双指针法 中心点外扩&#xff0c;注意中心点可能有一个元素可能有两个…