我的编程空间,编程开发者的网络收藏夹
学习永远不晚

React-Route6实现keep-alive效果

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

React-Route6实现keep-alive效果

一、基于react-route6  useOutlet实现

二、代码呈现

import React, { useRef, createContext, useContext } from 'react'
import { useOutlet, useLocation, matchPath } from 'react-router-dom'
import type { FC } from 'react'
//在组件外部建立一个Context
export const KeepAliveContext = createContext<KeepAliveLayoutProps>({ keepalive: [], keepElements: {} })

//给予页面缓存设置条件判断
const isKeepPath = (aliveList: any[], path: string) => {
  let isKeep = false
  aliveList.map(item => {
    if (item === path) {
      isKeep = true
    }
    if (item instanceof RegExp && item.test(path)) {
      isKeep = true
    } 
  })
  return isKeep
}
//判断当前页面是否已缓存,是则控制hidden开关显示 ,不是则正常渲染
export function useKeepOutlets() {
  const location = useLocation()
  const element = useOutlet()
  const { keepElements, keepalive } = useContext<any>(KeepAliveContext)
  const isKeep = isKeepPath(keepalive, location.pathname)
  if (isKeep) {
    keepElements.current[location.pathname] = element
  }
  //标签的显示与隐藏
  return <> {
    Object.entries(keepElements.current).map(([pathname, element]: any) => (
      <div key={pathname} 
      style={{ height: '100%', width: '100%', position: 'relative', overflow: 'hidden auto' }}       className="rumtime-keep-alive-layout" 
      hidden={!matchPath(location.pathname, pathname)}>
        {element}
      </div>
    ))
  }
    <div hidden={isKeep} style={{ height: '100%', width: '100%', position: 'relative', overflow: 'hidden auto' }} className="rumtime-keep-alive-layout-no">
      {!isKeep && element}
    </div>
  </>
}
//设置公共组件类型
interface KeepAliveLayoutProps {
  keepalive: any[]
  keepElements?: any
  dropByCacheKey?: (path: string) => void 
}
//封装公共组件
const KeepAliveLayout: FC<KeepAliveLayoutProps> = (props) => { 
  const { keepalive, ...other } = props
  const keepElements = React.useRef<any>({}) 
  function dropByCacheKey(path: string) { 
    keepElements.current[path] = null
   } return (<KeepAliveContext.Provider 
    value={{ keepalive, keepElements, dropByCacheKey }}
     {...other} />) 
    }
  
  export default KeepAliveLayout

代码分析

isKeepPath

配置 keepalive 支持字符串和正则,通过它来判断,当前页面是否需要状态保持,因为如果整个项目的页面都保持状态的话,对性能是很大的消耗

参数1为可缓存路径或正则表达式组成的数组,参数2为当前路径。

若当前路径在已缓存路径数组中或其路径符合正则表达式则isKeep为true,反之为false

useKeepOutlets

通过判断当前页面是否是需要保持的页面来对页面 DOM 做一个 hidden 显隐开关。

需要注意的是所有被指定状态保持的页面在首次渲染之后,都会被挂载在页面 DOM 树上,仅仅是使用 !matchPath(location.pathname, pathname) 控制显隐。

而没有被指定状态保持的页面,则是使用 {!isKeep && element} 控制,走 React 组件正常的生命周期。

location

当前路径信息

element

获取当前路由组件即当前配置下的嵌套路由组件

useContext<any>(KeepAliveContext)

通过useContext()钩子函数获取Context对象中的属性,已便于组件之间共享状态

isKeep

将当前路径利用页面缓存设置条件判断是否为已缓存路径,若符合条件,isKeep为true,则将keepElements Ref中以当前组件路径名为属性名的属性绑定当前路由组件

Object.entries

描述:Object.entries()返回一个数组,其元素是与直接在object上找到的可枚举属性键值对相对应的数组。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。

可枚举:枚举的功能类似于字面量类型+联合类型组合的功能,也可以表示一组明确的可选值

参数:可以返回其可枚举属性的键值对的对象

返回值:给定对象自身可枚举属性的键值对数组

key

保持 key 不变,就不会触发 React 的重绘

hidden

控制显示与隐藏开关

matchPath(location.pathname, pathname)}

所有被指定状态保持的页面在首次渲染之后,都会被挂载在页面 DOM 树上,仅仅是使用!matchPath(location.pathname, pathname) 控制显示隐藏。

//matchPath:参数1为当前路径,参数2为缓存路径,确定当前路由路径是否与缓存路径匹配

而没有被指定状态保持的页面,则是使用 {!isKeep && element} 控制,走 React 组件正常的生命周期

KeepAliveLayout

为封装后暴露的组件

FC

React.FC是函数式组件,是在TypeScript下使用的一个泛型,全称为React.FunctionComponentReact.FC<> 可检测指定属性类型

keepElements

使用 React.useRef<any>({}) 来做页面数据保存的节点,是因为我们的上下文不被重新渲染的话 keepElements 就不会被重置,相当于 key 

dropByCacheKey

dropByCacheKey为清除缓存的函数,通过控制当前组件的ref来销毁组件

other

const { keepalive, ...other } = props中...other为其他配置,这里我们直接遍历继承即可

Provider

(<KeepAliveContext.Provider value={{ keepalive, keepElements, dropByCacheKey }} {...other} />)

原理:

每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。

Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。

当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染

三、使用

import KeepAliveLayout, { useKeepOutlets, KeepAliveContext }from'@/components/KeepAliveLayout'
import { useLocation } from 'react-router-dom'
import React, { useState, useContext } from 'react'

// 使用KeepAliveLayout中的useKeepOutlets获取当前渲染的页面内容
const Layout = () => {
    const element = useKeepOutlets()
    return (
        {element}
    )
}
// 使用 KeepAliveLayout 包裹上下文
const App = () => {
    return (
        <KeepAliveLayout keepalive={[/./]}>//不可能组件都缓存吧所以需要设置缓存条件,可传可缓存的路径或正则表达式
            // App
        </KeepAliveLayout>
    );
}
// 使用 useContext 获取 dropByCacheKey 清除缓存
const Home = () => {
    const { dropByCacheKey } = useContext<any>(KeepAliveContext);
    const { pathname } = useLocation();
    return (
       <button onClick={() => dropByCacheKey(pathname)}>清除缓存</button>
    )
}

到此这篇关于React-Route6实现keep-alive效果的文章就介绍到这了,更多相关React-Route6 keep-alive 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

React-Route6实现keep-alive效果

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

vue3 keep-alive实现tab页面缓存功能

如何在我们切换tab标签的时候,缓存标签最后操作的内容,简单来说就是每个标签页中设置的比如搜索条件及结果、分页、新增、编辑等数据在切换回来的时候还能保持原样,这篇文章介绍vue3 keep-alive实现tab页面缓存功能,感兴趣的朋友一起看看吧
2023-05-17

Vue keep-alive的实现原理是什么

这篇“Vue keep-alive的实现原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue keep-alive
2023-06-30

Vue中如何对iframe实现keep alive无刷新

今天小编给大家分享一下Vue中如何对iframe实现keep alive无刷新的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
2023-07-04

react如何实现滑动效果

今天小编给大家分享一下react如何实现滑动效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。react实现滑动的方法:1、
2023-07-04

Vue3嵌套路由中使用keep-alive缓存多层的实现

本文介绍了Vue3嵌套路由中使用 keep-alive缓存多层的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-16

vue3如何使用keep alive实现前进更新后退销毁

这篇文章主要讲解了“vue3如何使用keep alive实现前进更新后退销毁”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue3如何使用keep alive实现前进更新后退销毁”吧!kee
2023-06-30

React如何实现轮播图效果

这篇文章主要介绍“React如何实现轮播图效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“React如何实现轮播图效果”文章能帮助大家解决问题。效果:轮播功能用到了react-slick组件,安装
2023-07-02

编程热搜

目录