Skip to content

Instantly share code, notes, and snippets.

@colus001
Last active January 8, 2018 02:57
Show Gist options
  • Save colus001/af9fe8742c26586f5c9d5765158be202 to your computer and use it in GitHub Desktop.
Save colus001/af9fe8742c26586f5c9d5765158be202 to your computer and use it in GitHub Desktop.
HOC to cache react component's state to local storage
import { omit, pick, isEmpty } from 'lodash'
import React from 'react'
import { isBrowser, get } from 'utils/misc'
const hasLocalStorage = isBrowser && !!localStorage
type Options = {
cacheKey: string,
whitelist: Array<string>,
blacklist: Array<string>,
}
const withLocalCache = (Element: React.node, options: Options) => {
const { cacheKey, whitelist, blacklist } = options
if (!hasLocalStorage || !cacheKey) return Element
if (!isEmpty(whitelist) && !isEmpty(blacklist)) {
throw new Error('Whitelist and black both can not applied at the same time')
}
const preserve = (state) => {
if (isEmpty(whitelist)) return pick(state, whitelist)
if (isEmpty(blacklist)) return omit(state, blacklist)
return state
}
const name = Element.displayName || Element.constructor.displayName || Element.constructor.name
return class extends Element {
displayName = name
constructor(props) {
super(props)
const preservedState = get(() => JSON.parse(localStorage.getItem(cacheKey)))
if (!preservedState) return
this.state = preservedState
}
componentDidUpdate(prevProps, prevState) {
const preserving = JSON.stringify(preserve(this.state))
localStorage.setItem(cacheKey, preserving)
super(prevProps, prevState)
}
}
}
export default withLocalCache
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment