Last active
September 10, 2020 14:52
-
-
Save Psvensso/16d51973709b996bdaf03a2f77aa8c9c to your computer and use it in GitHub Desktop.
React LocalStorage HOC that syncs component state to LocalStorage with whitelist
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 * as React from 'react'; | |
export function getLocalStorageItem<T>(key: string, ifNull: T) { | |
try { | |
var item = localStorage.getItem(key); | |
return item === null ? ifNull : JSON.parse(item); | |
} catch (e) { | |
localStorage.removeItem(key); | |
return ifNull; | |
} | |
} | |
export function saveLocalStorageItem(key: string, item) { | |
try { | |
localStorage.setItem(key, JSON.stringify(item)); | |
} catch (e) { | |
localStorage.removeItem(key); | |
} | |
} | |
let hasLocalStorage = !!localStorage; | |
if (hasLocalStorage) { | |
let testKey = 'react_fc9704944c8f'; | |
try { | |
// Access to global `localStorage` property must be guarded as it | |
// fails under iOS private session mode. | |
localStorage.setItem(testKey, 'foo') | |
localStorage.removeItem(testKey) | |
} catch (e) { | |
hasLocalStorage = false; | |
} | |
} | |
interface LocalStorageHOCOptions { | |
storrageKey: string; | |
whiteListObject?: MapLike<boolean>; | |
} | |
export const savesStateTolocalStorage = (args: LocalStorageHOCOptions) => | |
<TOriginalProps extends {}>(Component: (React.ComponentClass<TOriginalProps>)): React.ComponentClass<TOriginalProps> => { | |
const { storrageKey, whiteListObject } = args; | |
// Return Component if no localStorage is available | |
if (!hasLocalStorage) { | |
return Component; | |
} | |
let name = storrageKey; | |
class LocalStorageComponent extends Component { | |
componentDidCatch() { | |
localStorage.removeItem(name); | |
} | |
componentWillMount() { | |
this.setState(getLocalStorageItem<any>(name, {})); | |
} | |
componentWillUpdate(nextProps, nextState) { | |
if (this.state === nextState) { | |
return; | |
} | |
if (whiteListObject) { | |
let newState = {}; | |
Object.keys(whiteListObject).forEach((allowedKey) => { | |
if (!!nextState[allowedKey]) { | |
newState[allowedKey] = nextState[allowedKey]; | |
} | |
}); | |
saveLocalStorageItem(name, newState); | |
} else { | |
saveLocalStorageItem(name, nextState); | |
} | |
} | |
} | |
return LocalStorageComponent | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment