vue自带keepAlive功能这个大家都知道,但是如果是react呢?
react功能特别单一的,只维护视图和数据渲染同步部分,其余的依赖三方包。
今天讲的内容与第三方包reat-activation有关
封装
- import React, { useEffect } from 'react';
- import KeepAlive, { useAliveController } from 'react-activation';
- import type { FC } from 'react';
- interface Iprops {
- name: string;
- }
-
- const ChildDemo: FC<Iprops> = props => {
- const keepAliveKey = props.name;
- if (!keepAliveKey) {
- console.error('keepAlive 包装组件 的key不能为空');
- }
- const { dropScope } = useAliveController();
- // 关闭页签时清空缓存
- const clearCache = (e: any) => {
- console.log('关闭tab', e?.data?.deleteTab, keepAliveKey);
- if (e?.data?.deleteTab === keepAliveKey) {
- dropScope(keepAliveKey);
- }
- };
- //接受关闭当前页面的事件,这是特定项目的事件,请根据自己的项目来处理
- useEffect(() => {
- //这里是项目的api,其他地方未必会是这样
- window.addEventListener('message', clearCache, false);
- return () => {
- //页面销毁的时候,清空事件监听
- window.removeEventListener('message', clearCache, false);
- };
- }, []);
- return <div />;
- };
-
-
- /**
- * @param key 页面组件的文件路径 例如:'/baidu/something/doing'
- * @param children 要被包装的React页面组件
- * @returns
- */
- const KeepAliveBoundarie: FC<Iprops> = props => {
-
- const keepAliveKey = props.name;
-
- return (
- <KeepAlive name={keepAliveKey}>
- {props.children}
- <ChildDemo name={keepAliveKey} />
- </KeepAlive>
- );
- };
-
- export default KeepAliveBoundarie;
- import React from 'react';
- import { XpKeepAlive } from '@/components';
- import Demo from './kIndex';
- export default () => {
- return (
- <XpKeepAlive name='这里最好填写页面对应的路由路径,避免出现重复'>
- <Demo />
- </XpKeepAlive>
- );
- };
react-activation和react的context有一定的关系,如果你需要把缓存的功能抽到npm包时候,切记一定要保证npm里面的react版本和你的程序的react版本一样。
可以选择配置npm里面的react以你的项目的react版本为主(参考webpack externals),否则会出现两个react程序的情况,这样缓存由npm包里面的react维护,和你的主程序是隔离的。
作者对这个问题的回复链接