react中实现路由缓存和组件缓存

该思路适合单页面应用。

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;
  1. 新建路由组件(其实就时页面的壳子)
import React from 'react';
// 缓存组件,步骤一定义的
import ComponentCache from '@/component/cache';
// 页面里要显示的内容
import Cache from './cache';

export default () => {
  return (
    <ComponentCache cacheId="page/cache">
      <Cache></Cache>
    </ComponentCache>
  );
};
  1. 新建内容组件(其实就是页面里的内容)
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值