1. 事件起因

??之前做一个驾照考题的项目,有一个这样的问题,每当我选好了科目和驾照类型后(如图1),点击开始考试就会跳到考试页面(Test.tsx),并且在Test组件中对我架设的中间层发起请求获取数据(如图2)。

??如果用户手滑的话不小心点到了左上角的返回,或者狠狠地把屏幕往右滑动一下的话,都会返回到首页,再重新点击开始考试后进入到Test组件内又会重新发送请求获取随机题目,重新渲染题目列表,这样的话比较消耗性能吧,也是用户不愿意看到的。

??????????????图1 

                   图2

2. 解决方案

??利用「备忘录」设计模式。

??实现思路: 备忘录其实说白了就是做一次缓存,在发起请求之前先判断缓存中是否有我要请求的数据,如果有就走缓存,如果没有就重新请求,请求完了之后再把请求到的数据设置进缓存中。

??代码如下:

??src/QuesMemo/index.ts:

// 封装一个关于考题的备忘录类, 实例的cache对象中存放所有关于考题的数据
class QuesMemo {
  cache: any;
  static instance: any;
  constructor() {
    // cache中存放所有缓存的数据
    this.cache = {};
  }

  static getInstance() {
    if(!QuesMemo.instance) {
      Object.defineProperty(QuesMemo, 'instance', {
        value: new QuesMemo()
      });
    }
    return QuesMemo.instance;
  }

  // 将数据增添至信息缓存的方法
  addMemo(key: string, value: Array<any>) {
    this.cache[key] = value;
  }
}



export default QuesMemo.getInstance() as object;

??下面来到Test组件内,在请求之前先判断下缓存中有没有我要请求的数据,代码如下:

??src/views/Test.tsx:

// 这个是自定义的hook, 里面就是做了请求数据以及拿到数据后设置当前问题curQuestion的操作, 在Test组件内调用这个hook即可
export function useCurQuestion(): [ IQueryData | null, any ] {

  const subject: SUBJECTS = useSelector((state: IState) => state.curSubject);
  const model: MODELS = useSelector((state: IState) => state.model);
  
  const [ curQuestion, setCurQuestion ] = useState<IQueryData>(null);

  const dispatch: Dispatch = useDispatch();


  useEffect(() => {
    // 开始判断cache缓存中是否有我所需要的考题数据, 考题数据的key我定义为 subject-model 的形式
    if(quesMemo.cache[`${ subject }-${ model }`]) {
      // 如果有考题数据那我就走缓存
      let result: IQueryData[] = quesMemo.cache[ `${ subject }-${ model }` ];
      
      dispatch({ type: types.SET_QUERY_LIST, payload: result });
      setCurQuestion(result[0]);      // 重新进入Test从第一题开始答
    }else {
      // getQueries是向node中间层发起请求获取数据哈
      getQueries({ subject, model }).then(res => {
        console.log('res: ', res);
        dispatch({ type: types.SET_QUERY_LIST, payload: res.result });
        setCurQuestion(res.result[0]);
  
        // 获取到了新数据后再把数据丢入缓存
        quesMemo.addMemo( `${ subject }-${ model }`, res.result );
      });
    }
  
  }, [ subject, model, dispatch ]);

  return [ curQuestion, setCurQuestion ];
}

??以上就是备忘录设计模式的大致使用了,感觉思路挺简单的,就是做了一次缓存,请求之前判断有数据就走缓存,没数据就重新请求再丢进缓存。

??参考书籍 《JavaScript设计模式》 张容铭 著

标签智能推荐:

文章链接

ReactHook相关文章写ReactHooks前必读react-hooks如何使用?如何处理浏览器的断网情况?玩转react-hooks,自定义hooks设计模式及其实战五个大型项目实战总结,解密ReactHooks最佳实践方式「react缓存页面」从需求到开源(我是怎么样让产品小姐姐刮目相看的)React新特性React性能优化完全指南,将自己这几年的心血总结成这篇!TypeScript中使用

ReactReact-eslint报错(React Hook "useEffect" is called in function "routeClass3" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks

1y/anchor-is-valid":"off","@typescript-eslint/camelcase":"off","@typescript-eslint/explicit-function-return-type":"error","react-hooks/rules-of-hooks":"error",//检查Hook的规则"react-hooks/exhaustive-deps":

react hooks

俺不懂但是俺找到俩篇精选https://blog.csdn.net/weixin_43648947/article/details/102838142http://www.ruanyifeng.com/blog/2019/09/react-hooks.html

react-router-dom下的BrowserRouter和HashRouter

mponent={Home}/&gt;&lt;Routepath="/hooks"component={Hooks}/&gt;&lt;/Router&gt;)}操作一:浏览器直接输入localhost:3000/结果:路由自动变为localhost:3000/#/home,可正常访问.操作二:浏览器直接输入localhost:3000/#/hooks结果:可正常访问将HashRouter更改为Br

前端架构师图谱

章来源https://baijiahao.baidu.com/s?id=1651087264379443380&amp;wfr=spider&amp;for=pc#前言以下是获取到的一位阿里的前端架构师整理的前端架构p7的技能图谱,当然不是最完整、最系统的,所以之后我会一直维护更新这里的内容。技术架构考核范围vue.js&nbsp;react.js&nbsp;nodejs&nbsp;微信&nbsp

阿里P7前端需要哪些技能

分享阿里前端p7架构图谱前言以下是从公众号的文章中获取到的一位阿里的前端架构师整理的前端架构p7的技能图谱,当然不是最完整、最系统的,所以之后我会一直维护更新这里的内容,并且维护在个人前端小册的各个小册中,欢迎大家关注最新的文档更新。我的语雀前端小册链接:www.yuque.com/robinson/fe…重点是:免费+不断更新+可以微信交流。宗旨:从小白到大师,我们慢慢来。技术架构考核范围vue

设计模式

设计模式

react源码解析4.源码目录结构和调试

conciler等scripts:react构建相关下面来看下packages主要包含的模块react:核心Api如:React.createElement、React.Component都在这和平台相关render相关的文件夹:react-art:如canvassvg的渲染react-dom:浏览器环境react-native-renderer:原生相关react-noop-renderer:调

react源码解析4.源码目录结构和调试

conciler等scripts:react构建相关下面来看下packages主要包含的模块react:核心Api如:React.createElement、React.Component都在这和平台相关render相关的文件夹:react-art:如canvassvg的渲染react-dom:浏览器环境react-native-renderer:原生相关react-noop-renderer:调

高阶

体简述。3.hooks为什么不能在条件语句中使用?hooks的底层基于链表实现,为了保证每个状态能一一对应,必须保证hooks函数无条件执行。所以不能在循环、条件语句、return后等位置调用。4.hooks有什么优点?除了高阶函数的优点(略),还把高阶函数的不足给弥补了(如嵌套和ref转发、静态方法的丢失等)。且hooks使组件拥有了复用“生命周期”的能力,可以返回任意类型的数据,大大增加了逻辑