React實現元件快取的一種思路
阿新 • • 發佈:2020-09-03
前言
- 對於某個頁面中的某個元件,很多時候需要其保持一直啟用的狀態,之前我的部落格裡面有一篇提到一種快取策略,就是利用
Route
的children
方法來display
該元件或隱藏該元件。但是這種方式需要藉助到Route
元件並且只能快取整個頁面,而不是頁面中的部分元件。並且這種快取單純的只是在頁面上把它的display
變成了block
和none
,僅僅是在路由離開的時候不解除安裝掉該元件。 - 對此,還有一種思路也可以嘗試一下,就是在一個元件離開前去儲存它所有的
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
就可以像示例中一樣進行全域性引用。