Last active
January 8, 2018 02:57
-
-
Save colus001/af9fe8742c26586f5c9d5765158be202 to your computer and use it in GitHub Desktop.
HOC to cache react component's state to local storage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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