本文主要介绍了react-router-dom v6 通过outlet实现keepAlive 功能的实现,具体如下:

在这里插入图片描述

keepAlive代码:

import React, { useRef, useEffect, useReducer, useMemo, memo } from 'react'
import { TransitionGroup, CSSTransition } from 'react-transition-group'
import { useLocation } from 'react-router-dom'

const KeepAlive = props => {
    const { include, keys, children } = props
    const { pathname } = useLocation()
    const componentList = useRef(new Map())
    const forceUpdate = useReducer(bool => !bool)[1] // 强制渲染
    const cacheKey = useMemo(() => pathname   "__"   keys[pathname], [pathname, keys]) // eslint-disable-line
    const activeKey = useRef(null)

    useEffect(() => {
        componentList.current.forEach(function(value, key) {
            const _key = key.split("__")[0]
            if (!include.includes(_key) || (_key === pathname)) {
                this.delete(key) 
            }
        }, componentList.current)

        activeKey.current = cacheKey
        if (!componentList.current.has(activeKey.current)) {
            componentList.current.set(activeKey.current, children)
        }
        forceUpdate()
    }, [cacheKey, include]) // eslint-disable-line

    return (
        <TransitionGroup component={ null }>
            {
                Array.from(componentList.current).map(([key, component]) => 
                    <CSSTransition
                        key={ key }
                        appear={ true }
                        timeout={ 500 }
                        classNames='fade'>
                        {
                            key === activeKey.current ?
                            <div
                                className={
                                    `layout-container${include.includes(key.split("__")[0]) ? " keep-alive-fade": ""}`
                                }>
                                { component }
                            </div> :
                            <div
                                className='layout-container__keep-alive'
                                style={{ display: 'none' }}>
                                { component }
                            </div>
                        }
                    </CSSTransition>
                )
            }
        </TransitionGroup>
    )
}

export default memo(KeepAlive)

main.js 中调用

import PropTypes from 'prop-types'
import { useLocation, useOutlet } from 'react-router-dom'
import { connect } from 'react-redux'
import { Layout } from 'antd'
import { TransitionGroup, CSSTransition } from 'react-transition-group'
import KeepAlive from '@/components/common/keepAlive'
import { isKeepAlive } from '@/service/config'

const Main = props => {
    const { fullScreen, cacheRoutes, cacheKeys } = props
    const outlet = useOutlet()
    const { pathname } = useLocation()

    return (
        <Layout.Content className={{ "layout-main": true, "full-screen": fullScreen }}>
            <section>
                {
                	// isKeepAlive 生产环境中启用缓存
                    isKeepAlive ? 
                    <KeepAlive include={ cacheRoutes } keys={ cacheKeys }>
                        { outlet } // 此处不能用 <Outlet /> 不然无法通过 useRef 来缓存
                    </KeepAlive> :
                    <TransitionGroup component={ null }>
                        <CSSTransition
                            key={ pathname   cacheKeys[pathname] }
                            appear={ true }
                            timeout={ 500 }
                            classNames='page-fade'>
                            { outlet } // 此处不能用 <Outlet /> 会造成路由切换时,组件重复渲染
                        </CSSTransition>
                    </TransitionGroup>
                }
            </section>
        </Layout.Content>
    )
}

Main.propTypes = {
    fullScreen: PropTypes.bool,
    cacheRoutes: PropTypes.array,
    cacheKeys: PropTypes.object
}

const mapStateToProps = state => {
    return {
        fullScreen: state.setting.fullScreen,
        cacheRoutes: state.tabsBar.cacheRoutes, // 需要缓存的路由组件path数组
        cacheKeys: state.tabsBar.cacheKeys // 用于组件局部刷新
    }
}

export default connect(mapStateToProps)(Main)

1、当前图片动画中,只设置了第二个标签页缓存,其他的几个未开启缓存,所以可以看到,只有第二个标签页在切回的时候 未重新请求数据。其他标签页每次进入都会重新请求数据。
2、此外这里结合react-transition-group 实现了路由切换的渐隐渐显动画,但需要手动配合css样式控制,不能完全依靠CSSTransition
代码部分:

// 路由进入动画
.fade-enter, .fade-appear {
    opacity: 0;
}
.fade-enter-active, .fade-appear-active {
    opacity: 1;
    @include transition(opacity .25s cubic-bezier(.645, .045, .355, 1) .25s);
}
.fade-exit {
    opacity: 1;
    z-index: 1;
}
.fade-exit-active {
    opacity: 0;
    z-index: 1;
    @include transition(opacity .25s cubic-bezier(.645, .045, .355, 1));
}
.page-fade-enter, .page-fade-appear {
    opacity: 0;
}
.page-fade-enter-active, .page-fade-appear-active {
    opacity: 1;
    @include transition(opacity .5s cubic-bezier(.645, .045, .355, 1));
}
.page-fade-exit {
    opacity: 1;
    display: none!important;
}
.page-fade-exit-active {
    opacity: 0;
}
@keyframes keepAliveFade {
  0% { opacity: 0; }
  50% { opacity: 0; }
  100% { opacity: 1; }
}
.layout-container {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    &.keep-alive-fade { animation: keepAliveFade .5s ease-in-out; }
}

到此这篇关于react-router-dom v6 通过outlet实现keepAlive 功能的实现的文章就介绍到这了,更多相关react-router keepAlive 内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

react-router-dom v6 通过outlet实现keepAlive 功能的实现的更多相关文章

  1. 如何在Android中设置keepalive超时?

    看起来我可以这样做,如果我使用NDK,但我想将此代码分发为jar,所以这对我来说并不理想.解决方法这可能是一个非常明显的答案[即它不是你特定案例的选项]但是你当然可以通过每10分钟发送1个丢弃字节来实现你自己的keepalive.

  2. 五分钟理解keep alive用法及原理

    这篇文章主要为大家介绍了keep alive用法及原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  3. react 路由权限动态菜单方案配置react-router-auth-plus

    这篇文章主要为大家介绍了react路由权限动态菜单方案react-router-auth-plus傻瓜式配置详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. Vue3-KeepAlive,多个页面使用keepalive方式

    这篇文章主要介绍了Vue3-KeepAlive,多个页面使用keepalive方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  5. vue3中使用router4 keepalive的问题

    这篇文章主要介绍了vue3中使用router4 keepalive的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  6. vue自定义keepalive组件的问题解析

    这篇文章主要介绍了vue自定义keepalive组件的相关资料,keep-alive组件是使用 include exclude这两个属性传入组件名称来确认哪些可以被缓存的,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  7. vue项目keepAlive配合vuex动态设置路由缓存方式

    vue项目keepAlive配合vuex动态设置路由缓存方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  8. react-router browserHistory刷新页面404问题解决方法

    本篇文章主要介绍了react-router browserHistory刷新页面404问题解决方法,非常具有实用价值,需要的朋友可以参考下

  9. Vue项目中keepAlive的使用说明(超级实用版)

    这篇文章主要介绍了Vue项目中keepAlive的使用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  10. react-router v6实现动态路由实例

    这篇文章主要为大家介绍了react-router v6实现动态路由实例详解,<BR>有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部