前言:

因为 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。而且 作者也让关注 。

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.请勿使用 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 属性,以保证该高速缓存的稳定性,如下所示:

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

官网示例:

// App.js

import React, { useState } from 'react'

import KeepAlive from 'react-activation'

function Counter() {

const [count, setCount] = useState(0)

return (

count: {count}

)

}

function App() {

const [show, setShow] = useState(true)

return (

{show && (

)}

)

}

export default App

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

配合路由使用react-activation

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

{

path: "/",

component: ,

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 {component};

}

return <>{component};

};

const App = () => {

return (

{routes.map((route) => (

key={route.path}

path={route.path}

//element={route.component }

// 专门负责显示页面标题

element={}

/>

))}

);

};

还可以手动清除缓存

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。

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

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。