1. 程式人生 > 實用技巧 >React實現元件快取的一種思路

React實現元件快取的一種思路

前言

  • 對於某個頁面中的某個元件,很多時候需要其保持一直啟用的狀態,之前我的部落格裡面有一篇提到一種快取策略,就是利用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就可以像示例中一樣進行全域性引用。