React实现页面状态缓存(keep-alive)的示例代码

 更新时间:2024年01月23日 09:45:58   作者:崽崽的谷雨  
因为 react、vue都是单页面应用,路由跳转时,就会销毁上一个页面的组件,但是有些项目不想被销毁,想保存状态,本文给大家介绍了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.js

import 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",
  }

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) => (
          <Route
            key={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 使用文档

以上就是React实现页面状态缓存(keep-alive)的示例代码的详细内容,更多关于React页面状态缓存的资料请关注脚本之家其它相关文章!

相关文章

  • 浅谈React组件props默认值的设置

    浅谈React组件props默认值的设置

    本文主要介绍了浅谈React组件props默认值的设置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • react中useState改变值不渲染的解决方式

    react中useState改变值不渲染的解决方式

    这篇文章主要介绍了react中useState改变值不渲染的解决方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • 基于React实现虚拟滚动的方案详解

    基于React实现虚拟滚动的方案详解

    这篇文章将以固定高度和非固定高度两种场景展开React中虚拟滚动的实现,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-03-03
  • React各种状态管理器的解读及使用方法

    React各种状态管理器的解读及使用方法

    这篇文章主要介绍了对于React各种状态管理器的解读,文中给大家提到了状态管理器是如何使用的,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • React Context源码实现原理详解

    React Context源码实现原理详解

    这篇文章主要为大家介绍了React Context源码实现原理示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • React中进行条件渲染的实现方法

    React中进行条件渲染的实现方法

    React是一种流行的JavaScript库,它被广泛应用于构建Web应用程序,在React中,条件渲染是一个非常重要的概念,它允许我们根据不同的条件来呈现不同的内容,在本文中,我们将探讨React如何进行条件渲染,需要的朋友可以参考下
    2023-11-11
  • React中实现组件通信的几种方式小结

    React中实现组件通信的几种方式小结

    在构建复杂的React应用时,组件之间的通信是至关重要的,从简单的父子组件通信到跨组件状态同步,不同组件之间的通信方式多种多样,下面我们认识react组件通信的几种方式,需要的朋友可以参考下
    2024-04-04
  • React八大常见错误及其解决方案

    React八大常见错误及其解决方案

    这篇文章主要介绍了React八大常见错误及其解决方案,并通过代码示例介绍的非常详细,对大家学习react有一定的帮助,感兴趣的朋友可以参考下
    2024-03-03
  • 详解如何在React中监听鼠标事件

    详解如何在React中监听鼠标事件

    React可以通过使用React事件系统来监听鼠标事件,您可以在React组件中通过使用特定的事件处理函数来注册和处理鼠标事件,本文小编讲给大家详细介绍一下如何在React中监听鼠标事件,需要的朋友可以参考下
    2023-09-09
  • React如何解决样式污染问题

    React如何解决样式污染问题

    这篇文章主要介绍了React如何解决样式污染问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11

最新评论