preface

In the daily development of H5, it is often encountered that the list is clicked to enter details and then returned to the list. Different from APP, APP is a layer upon layer of View covered with LastPage, which can naturally save the state of the LastPage. However, unlike H5, all the states returned from details to the list will be cleared. Walking through the lifecycle again, if the list is long, clicking on details and then going back to the top of the list can be very frustrating to the user experience, so list caching is a must, followed by CacheHoc implementation.

thinking

Caching caching is basically two things: when a page leaves, and when it reenters, it retrieves data. When and where? When and where to get it?

When to deposit

This problem is very simple, of course, is the page is about to destroy the time to save, also known as componentWillUnmount life cycle to save operation.

Where there is

  1. If the data is persistent, it can be saved tourllocalStorageIn whichurlYou can firstpassDrop, because in the case of a complex list, there’s a lot of data that needs to be stored, all of iturlWill makeurlLong, obviously not right,localStorageIt’s a way of providinggetItem,setItemThe API is also sufficient to support access operations, up to 5M, the capacity is sufficient, and can also be serializedSerializeIntegration.
  2. Memory, for lists or data that don’t need to be persisted, memory is probably a better way to do that, why is that, for example, if you go from list -> detail -> list you need to cache that’s fine, but if you go back to the home page and re-enter the list logically you shouldn’t be using cached data before, So we can put it inreduxrematchState management tools, such as state management tools, encapsulate access methods, which are convenient, or put globallywindowIn the.

When to take

This problem is simple enough to fetch at page entry, but it is important to note that only fetch at POP, because every time we PUSH, we should enter a new page, and we should not use cached data in this case.

Where to take

CacheHocCache scheme based on

CacheHoc is a higher-order component where cached data is stored in a window. We simply pass in CACHE_NAME, scrollElRefs. CACHE_NAME is the key used to cache data. ScrollElRefs is an array containing scrollElRefs, which is used to record the scrollTop and state of the corresponding scrollElRefs in the life cycle function componentWillUnmount. Initialize State in Constructor and update scrollTop in componentDidMount.

Simple to use

import React from 'react'
import { connect } from 'react-redux'
import cacheHoc from 'utils/cache_hoc'

@connect(mapStateToProps, mapDispatch)
@cacheHoc export default class extends React.Component {  constructor (. props) {  super(... props) this.props.withRef(this)  }   / / set CACVHE_NAME  CACHE_NAME = `customerListThe ${this.props.index}`;   scrollDom = null   state = {  orderBy: '2'. loading: false. num: 1. dataSource: [],  keyWord: undefined  }   componentDidMount () {  // Set the scroll container list  this.scrollElRefs = [this.scrollDom]  // Request data to update state  }   render () {  const { history } = this.props  const { dataSource, orderBy, loading } = this.state   return (  <div className={gcmc('wrapper')} > <MeScroll  className={gcmc('wrapper')}  getMs={ref= > (this.scrollDom = ref)}  loadMore={this.fetchData}  refresh={this.refresh}  up={{  page: {  num: 1.// The current page number, which defaults to 0, will be incremented by 1 before the callback, i.e. callback(page) will start at 1  size: 15 // The amount of data per page  // time: null // The first page of data server return time; Prevent the user to turn the page, the background added data, resulting in the next page data duplication;  }  }}  down={{ auto: false }}  >  {loading ? (  <div className={gcmc('loading-wrapper')} > <Loading />  </div>  ) : (  dataSource.map(item => (  <Card  key={item.clienteleId}  data={item} {... this.props} onClick={() =>  history.push('/detail/id')  }  />  ))  )}  </MeScroll>  <div className={styles['sort']} > <div className={styles['sort-wrapper']} onClick={this._toSort}> <span style={{marginRight: 3}}> </span> <img  src={orderBy === '2'? SORT_UP : SORT_DOWN} alt='sort'  style={{ width: 10, height: 16 }}  />  </div>  </div>  </div>  )  } }  Copy the code

The effect is as follows:


Cached data:


code

const storeName = 'CACHE_STORAGE'
window[storeName] = {}

export default Comp => {
  return class CacheWrapper extends Comp {
 constructor (props) {  super(props)  if (!window[storeName][this.CACHE_NAME]) {  // Initializes the cache key according to CACHE_NAME  window[storeName][this.CACHE_NAME] = {}  }  // Used to store information such as state  this.store = window[storeName][this.CACHE_NAME]  const { history: { action } = {} } = props  // State is initialized only if a value is returned in &state  if (action === 'POP') {  const { state } = this.store  if (state) {  this.state = state  }  } else {  // When you enter the list again, i.e. from the home page, clear the last cached information  window[storeName][this.CACHE_NAME] = {}  this.store = window[storeName][this.CACHE_NAME]  }  }   async componentDidMount () {  if (super.componentDidMount) {  await super.componentDidMount()  }  const { history: { action } = {} } = this.props  if(action ! = ='POP') return  const { scrollTops = [] } = this.store  const { scrollElRefs = [] } = this  scrollElRefs.forEach((el, index) = > {  if(el && el.scrollTop ! = =undefined) {  el.scrollTop = scrollTops[index]  }  })  }   componentWillUnmount () {  if (super.componentWillUnmount) {  super.componentWillUnmount()  }  this.store.state = this.state  const scrollTops = []  const { scrollElRefs = [] } = this  scrollElRefs.forEach(ref= > {  if(ref && ref.scrollTop ! = =undefined) {  scrollTops.push(ref.scrollTop)  }  })  this.store.scrollTops = scrollTops  }  } }  Copy the code

conclusion

In fact, the way of caching are similar, on the above points, the specific scheme to be used according to the actual application scenarios to choose, it is important to analyze the timing and location of access, the realization is just to write out the logic in the brain.

This article is formatted using MDNICE