该思路适合单页面应用。
1.新建一个缓存组件,我们叫它componentCache,其核心方法就是每一个缓存组件都对应一个唯一的id,id都对应挂载再window对象上的productCache属性里,即id为pageA的缓存组件,它的缓存数据再window.productCache.pageA里
// componentCache.tsx
import React, { FunctionComponent, useEffect, useState } from 'react';
import { ReactElement } from 'react-router/node_modules/@types/react';
interface ICacheProps {
cacheId: string;
children: ReactElement;
}
interface IWindow extends Window {
projectCache?: {
[propName: string]: any;
};
}
const Cache: FunctionComponent<ICacheProps> = ({ cacheId, children }) => {
// 映射一个全局对象到window对象上
const globalThis: IWindow = window;
// 初始化的时候判断该cacheId对应再window对象上是否有数据,有就赋值给useCache,没有就赋值空对象
const [useCache, setUseCache] = useState(
globalThis.projectCache && globalThis.projectCache[cacheId]
? globalThis.projectCache[cacheId]
: {},
);
// 暴露一个修改缓存数据的方法,合并传入的state到缓存数据中
const onDraw = (state: any) => {
const newState = { ...useCache, ...state };
setUseCache(newState);
globalThis.projectCache && (globalThis.projectCache[cacheId] = newState);
};
// 组件初始化同步useState和window上的数据
useEffect(() => {
if (!globalThis.projectCache) globalThis.projectCache = {};
if (globalThis.projectCache[cacheId]) {
setUseCache(globalThis.projectCache[cacheId]);
} else {
setUseCache({});
globalThis.projectCache[cacheId] = {};
}
}, []);
return (
<div id={cacheId} style={{ height: '100%' }}>
{/* 将缓存数据和修改缓存数据的方法传递给该缓存组件传入的子组件中 */}
{React.cloneElement(children, { useCache, onDraw })}
</div>
);
};
export default Cache;
- 新建路由组件(其实就时页面的壳子)
import React from 'react';
// 缓存组件,步骤一定义的
import ComponentCache from '@/component/cache';
// 页面里要显示的内容
import Cache from './cache';
export default () => {
return (
<ComponentCache cacheId="page/cache">
<Cache></Cache>
</ComponentCache>
);
};
- 新建内容组件(其实就是页面里的内容)
import React, { FunctionComponent, useState, useEffect } from 'react';
interface IProps {
useCache?: any;
onDraw?: Function;
}
const Cache: FunctionComponent<IProps> = ({
useCache = {},
onDraw = () => {},
}) => {
const [count, setCount] = useState<number>(1);
useEffect(() => {
// 如果缓存里有数据,设置缓存数据给count
if (useCache && Object.keys(useCache).length !== 0) {
setCount(useCache.count);
}
}, []);
return (
<div>
<p>数: {count}</p>
<button
onClick={() => {
setCount(count + 1);
// 每次加一,同步缓存数据
onDraw({
count: count + 1,
});
}}
>
加一
</button>
</div>
);
};
export default Cache;
参考:https://segmentfault.com/a/1190000023263395/
https://zhuanlan.zhihu.com/p/214166951