React实现组件缓存的一种思路

摘要:
代码实现constkeepAlive=(Comp)=>}componentWillUnmount(){conststate=this.comp.state;cache={…state};}render(){return(<Compref={comp=>this.comp=comp}{…this.props}/>

前言

  • 对于某个页面中的某个组件,很多时候需要其保持一直激活的状态,之前我的博客里面有一篇提到一种缓存策略,就是利用Routechildren方法来display该组件或隐藏该组件。但是这种方式需要借助到Route组件并且只能缓存整个页面,而不是页面中的部分组件。并且这种缓存单纯的只是在页面上把它的display变成了blocknone,仅仅是在路由离开的时候不卸载掉该组件。
  • 对此,还有一种思路也可以尝试一下,就是在一个组件离开前去保存它所有的state值,等到下次渲染组件的时候把上次卸载钱的state值还原回来,不就可以使得,组件重新渲染后依然是上一次离开前的状态吗。

实现思路

  • 给需要缓存的组件加一层高阶组件,在高阶组件中通过ref获取到该组件的实例。
  • ComponentDidMount中通过ref获取到的实例,调用组件的setState方法,把缓存的上一次的state数据注入进去。
  • ComponentWillUnmount中通过ref获取到的实例,去获取其所有state的值,并存在缓存中。

代码实现

const keepAlive = (Comp) => {

  let cache = {};

  return class Alive extends React.Component {

    componentDidMount() {
      const state = this.comp.state;
      this.comp.setState({ ...state, ...cache });
    }

    componentWillUnmount() {
      const state = this.comp.state;
      cache = { ...state };
    }

    render() {
      return (
        <Comp ref={comp => this.comp = comp} { ...this.props } />
      )
    }
  }
}
  • 使用
import React from 'react';
import keepAlive from 'keep-alive-react';

class Test extends React.Component {
  state = {
    count: 0
  }

  render() {
    const { count } = this.state;
    return (
      <div className="Test">
      Test
      <div>count: {count}</div>
      <div onClick={() => {
        this.setState({
          count: count + 1
        })
      }}>add</div>
    </div>
    );
  }
}

export default keepAlive(Test);

小结

  • 目前该实现方式,暂不能支持函数式组件,函数式组件的状态都是使用的hooks写法,而hooks写法中无法便捷统一的去获取其组件所有的state值,并且也无法针对函数式组件去拿到该组件内部的引用,导致该思路只能给继承自React.Component的组件使用。
  • 该方法已经发布到npm上。直接使用npm i keep-alive-react --save就可以像示例中一样进行全局引用。

免责声明:文章转载自《React实现组件缓存的一种思路》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)Pandas系列教程(3)Pandas数据查询下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python 安装新的模块

一、方法1: 单文件模块直接把文件拷贝到 $python_dir/Lib 二、方法2: 多文件模块,带setup.py 下载模块包,进行解压,进入模块文件夹,执行:python setup.py install 三、 方法3:easy_install 方式  先下载ez_setup.py,运行python ez_setup 进行easy_install工具...

SSO单点登录和CAS

一、单点登录流程 =====客户端====== 1.拦截客户端的请求判断是否有局部的session 2.1如果有局部的session,放行请求. 2.2如果没有局部session 2.2.1请求中有携带token参数 2.2.1.1如果有,使用HttpURLConnection发送请求校验token是否有效. 2.2.1.1.1如果token有效,建立局部...

26.怎样在Swift中定义宏?

  Swift 中没有宏定义,苹果建议使用let 或者 get 属性来替代宏定义值。虽然没有#define,但我们仍然可以使用 #if 并配合编译的配置来完成条件编译。下面会列出Swift项目开发中的一些常用宏定义,并提供源码。 1.常用字体宏定义 import Foundation import UIKit /// 系统普通字体 var gof_Sy...

char码值对应列表大全

Char("0") 为0的字符Char("1")Char("2")Char("3")Char("4")Char("5")Char("6")Char("7") 响铃Char("8") 回格Char("9") tab(水平制表符)Char("10") 换行Char("11") tab(垂直制表符)Char("12") 换页Char("13") 回车 chr(1...

Linux平台下使用rman进行oracle数据库迁移

    实验目的:将oracle数据库从一台机器迁移到另外的一台机器(同为linux平台),设置为不同的路径,不同的实例名 源端: ORACLE_BASE=/u01/app/oracle ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1 ORACLE_SID=test 数据文件位置:/oradata/te...

PLSQL常用配置之窗口/版面保存、SQL格式化/美化、SQL注释去掉注释等快捷键配置、登陆历史修改配置

http://blog.csdn.net/hyeidolon/article/details/8251791   PLSQL常用配置之窗口/版面保存、SQL格式化/美化、SQL注释去掉注释等快捷键配置、登陆历史修改配置1、PL/SQL Developer记住登陆密码 在使用PL/SQL Developer时,为了工作方便希望PL/SQL Develop...