React實(shí)現(xiàn)頁(yè)面狀態(tài)緩存(keep-alive)的示例代碼
前言:
因?yàn)?react、vue都是單頁(yè)面應(yīng)用,路由跳轉(zhuǎn)時(shí),就會(huì)銷(xiāo)毀上一個(gè)頁(yè)面的組件。但是有些項(xiàng)目不想被銷(xiāo)毀,想保存狀態(tài)。
比如:h5項(xiàng)目跳轉(zhuǎn)其他頁(yè)面返回時(shí),頁(yè)面狀態(tài)不丟失。設(shè)想一個(gè) 頁(yè)面我滑倒了中間,然后跳轉(zhuǎn)到 詳情頁(yè)然后 返回,之前的頁(yè)面刷新了,回到頂部了肯定不行(搜索條件之類(lèi)的消失了,滾動(dòng)條回到頂部了)!
比如:pc端項(xiàng)目后臺(tái)管理項(xiàng)目里點(diǎn)擊時(shí) 打開(kāi)一個(gè)頁(yè)簽,頁(yè)簽切換,狀態(tài)頁(yè)會(huì)丟失。每次切換頁(yè)簽都重新請(qǐng)求了接口。
解決方案:
方案調(diào)研:
經(jīng)過(guò)我的調(diào)研:
我找到的 第三放庫(kù)有:
react-activation
umi-plugin-keep-alive
umi-plugin-keep-alive-tabs
react-keepalive-router
react-router-cache-route
redux、dva等(狀態(tài)共享插件)
react-keepalive-router、react-router-cache-route:
react-keepalive-router、react-router-cache-route 是個(gè)人開(kāi)發(fā)的,github上issues里的建議也沒(méi)及時(shí)回答。所以我就放棄了,沒(méi)考慮。
Offscreen:
Offscreen是react 18.x出的實(shí)驗(yàn)性api,所以我也放棄了。可以看react Offscreen
不過(guò) 此api如果正式使用的話,應(yīng)該是最好的選擇。其原理就是 把頁(yè)面 隱藏起來(lái),不銷(xiāo)毀組件樹(shù)。其實(shí)其他 插件原理也是這樣。
umi-plugin-keep-alive、umi-plugin-keep-alive-tabs:
umi-plugin-keep-alive、umi-plugin-keep-alive-tabs 是umi里的,是阿里開(kāi)發(fā)的,優(yōu)先考慮的就是這個(gè),但看了 文檔發(fā)現(xiàn) 它基于 react-activation。而且 作者也讓關(guān)注 。
其實(shí) 如果你項(xiàng)目是 umi的話 用 umi-plugin-keep-alive也可以(低版本umi可能不行)。antd-pro
若依等等基于umi搭建的庫(kù)都可以使用umi-plugin-keep-alive。這個(gè)插件 和umi綁定,所以我也放棄了,但應(yīng)該也可以單獨(dú)使用(我沒(méi)試過(guò))。
redux等狀態(tài)共享插件,需要項(xiàng)目搭建時(shí)就使用,原理就是,頁(yè)面里不寫(xiě) useState和state全都放到 store里。然后對(duì)整個(gè)store緩存。每次進(jìn)入頁(yè)面 判斷一下有緩存就走緩存,沒(méi)有重新請(qǐng)求。像redux之類(lèi)的都有持久化插件,配合持久化插件就很容易實(shí)現(xiàn)。缺點(diǎn)是繁瑣,且破壞了 不優(yōu)雅,頁(yè)面里不能寫(xiě)狀態(tài)。而且 還要額外 記錄滾動(dòng)條的位置。
react-activation:
所以綜上我選擇了 react-activation 它是路由級(jí)別的緩存。
react-activation基礎(chǔ)使用步驟及配置:
React Activation 僅支持 React 16 及以上版本
注意:
1.請(qǐng)勿使用 <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 插件
該插件在編譯過(guò)程中為每個(gè)JSX元素添加了一個(gè) _nk 屬性,以幫助 react-activation 運(yùn)行時(shí)根據(jù) react-node-key 的渲染位置生成唯一的標(biāo)識(shí)符。
{ "plugins": [ "react-activation/babel" ] }
如果不想使用Babel,建議每個(gè) 聲明一個(gè)全局唯一不變的 cacheKey 屬性,以保證該高速緩存的穩(wěn)定性,如下所示:
<KeepAlive cacheKey="UNIQUE_ID" />
2.import KeepAlive 然后包裹要緩存的組件 或者元素。
官網(wǎng)示例:
// 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.將 外層放置在不會(huì)卸載的位置,通常在應(yīng)用入口處
配合路由使用react-activation
1.isCache是自定義的屬性,用來(lái)標(biāo)識(shí)是否 緩存。true就是改路由需要緩存。
{ path: "/", component: <Initial />, title: "主頁(yè)", name: "initPage", isCache: true, cacheKey: "home", }
App.js 入口文件 或者 路由配置頁(yè)面里 封裝一層 根據(jù) isCache值來(lái)確定是否使用 keepAlive包裹。如下:
import React from "react"; import { BrowserRouter, Routes, Route, HashRouter } from "react-router-dom"; import routes from "./routes.js"; import KeepAlive from "react-activation"; // 封裝一層 專(zhuān)門(mén)負(fù)責(zé)顯示頁(yè)面標(biāo)題 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 } // 專(zhuān)門(mén)負(fù)責(zé)顯示頁(yè)面標(biāo)題 element={<DomTitle route={route} />} /> ))} </Routes> </HashRouter> ); };
還可以手動(dòng)清除緩存
import { useActivate, useUnactivate, withActivation, withAliveScope, useAliveController, } from "react-activation"; const { drop, dropScope, clear, getCachingNodes } = useAliveController(); console.log(getCachingNodes(), "緩存節(jié)點(diǎn)"); //drop("homePage"); // 手動(dòng)關(guān)閉某個(gè)頁(yè)面 // dropScope("detailPage"); dropScope("homePage"); // 參數(shù)就是上面定義的 cacheKey
還需要 將 外層放置在不會(huì)卸載的位置,通常在應(yīng)用入口處我的項(xiàng)目時(shí)create-react-app 是index.js。
具體 api使用方法和注意事項(xiàng)請(qǐng)看:
具體api可以看(如果 github打不開(kāi)可以看npm的,npm是英文的,可以用edge瀏覽器 翻譯一下):
以上就是React實(shí)現(xiàn)頁(yè)面狀態(tài)緩存(keep-alive)的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于React頁(yè)面狀態(tài)緩存的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Vue中Keep-Alive緩存組件使用語(yǔ)法及原理深度解析
- Vue3除了keep-alive還有哪些實(shí)現(xiàn)頁(yè)面緩存詳解
- Vue路由組件的緩存keep-alive和include屬性的具體使用
- Vue keep-alive組件的使用及如何清除緩存
- vue3?keep-alive實(shí)現(xiàn)tab頁(yè)面緩存功能
- Vue3嵌套路由中使用keep-alive緩存多層的實(shí)現(xiàn)
- vue使用keep-alive進(jìn)行組件緩存方法詳解(組件不緩存問(wèn)題解決)
- vue中keep-alive組件實(shí)現(xiàn)多級(jí)嵌套路由的緩存
- 快速解決 keep-alive 緩存組件中定時(shí)器干擾問(wèn)題
相關(guān)文章
淺談React組件props默認(rèn)值的設(shè)置
本文主要介紹了淺談React組件props默認(rèn)值的設(shè)置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04基于React實(shí)現(xiàn)虛擬滾動(dòng)的方案詳解
這篇文章將以固定高度和非固定高度兩種場(chǎng)景展開(kāi)React中虛擬滾動(dòng)的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-03-03React?Context源碼實(shí)現(xiàn)原理詳解
這篇文章主要為大家介紹了React?Context源碼實(shí)現(xiàn)原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10React中進(jìn)行條件渲染的實(shí)現(xiàn)方法
React是一種流行的JavaScript庫(kù),它被廣泛應(yīng)用于構(gòu)建Web應(yīng)用程序,在React中,條件渲染是一個(gè)非常重要的概念,它允許我們根據(jù)不同的條件來(lái)呈現(xiàn)不同的內(nèi)容,在本文中,我們將探討React如何進(jìn)行條件渲染,需要的朋友可以參考下2023-11-11React中實(shí)現(xiàn)組件通信的幾種方式小結(jié)
在構(gòu)建復(fù)雜的React應(yīng)用時(shí),組件之間的通信是至關(guān)重要的,從簡(jiǎn)單的父子組件通信到跨組件狀態(tài)同步,不同組件之間的通信方式多種多樣,下面我們認(rèn)識(shí)react組件通信的幾種方式,需要的朋友可以參考下2024-04-04詳解如何在React中監(jiān)聽(tīng)鼠標(biāo)事件
React可以通過(guò)使用React事件系統(tǒng)來(lái)監(jiān)聽(tīng)鼠標(biāo)事件,您可以在React組件中通過(guò)使用特定的事件處理函數(shù)來(lái)注冊(cè)和處理鼠標(biāo)事件,本文小編講給大家詳細(xì)介紹一下如何在React中監(jiān)聽(tīng)鼠標(biāo)事件,需要的朋友可以參考下2023-09-09