Skip to content

Instantly share code, notes, and snippets.

@ravid7000
Last active February 24, 2021 07:14
Show Gist options
  • Save ravid7000/6a99a5efc18011b3e3bb4303edf1b73a to your computer and use it in GitHub Desktop.
Save ravid7000/6a99a5efc18011b3e3bb4303edf1b73a to your computer and use it in GitHub Desktop.
import { useCallback, useState, useEffect } from 'react';
function hasLocalStorageSupport() {
try {
if (typeof window === 'undefined') {
return false;
}
if (typeof localStorage === 'undefined' || typeof sessionStorage === 'undefined') {
return false;
}
} catch(e) {
return false;
}
return true;
}
function parse(input) {
let value
try {
value = JSON.parse(input)
if (typeof value === 'undefined') {
value = input
}
if (value === 'true') {
value = true
}
if (value === 'false') {
value = false
}
if (parseFloat(value) === value && typeof value !== 'object') {
value = parseFloat(value)
}
} catch (e) {
value = input
}
return value
}
const hasSupport = hasLocalStorageSupport();
const STORAGE_TYPE = ['localStorage', 'sessionStorage'];
/**
* React hook to use browser's storage. Currenlty supporting localStorage and sessionStorage.
*
* @example
* import { useBrowserStorage } from 'use-local-storage';
*
* const { getItem, setItem, removeItem } = useBrowserStorage();
*
*
* @example
* // use sessionStorage
* const { getItem, setItem, removeItem } = useBrowserStorage({ type: 'sessionStorage' });
*
*
* @example
* // use timestamp with the value
* const { getItem, setItem, removeItem } = useBrowserStorage({ timestamp: true });
*
* setItem('token', 'token_value');
*
* getItem('token');
* // { value: 'token_value', timestamp: '2021-02-23T09:06:29.645Z' }
*
* @param options
*/
export const useBrowserStorage = (options = {}) => {
const [count, updateCount] = useState(0);
const storageType = STORAGE_TYPE.includes(options.type) || STORAGE_TYPE[0];
const timestamp = (options && options.timestamp) || false;
const forceUpdate = (options && options.forceUpdate) || false;
const storage = window[storageType];
const getItem = useCallback((name) => {
if (hasSupport) {
const value = storage.getItem(name);
if (value) return parse(value);
}
}, [storageType, timestamp, count]);
const setItem = useCallback((name, value) => {
let oldValue;
if (hasSupport) {
oldValue = parse(storage.getItem(name));
if (timestamp) {
storage.setItem(name, JSON.stringify({
value,
timestamp: new Date()
}))
} else {
storage.setItem(name, JSON.stringify(value));
}
if (forceUpdate) {
updateCount(safeUpdateCount);
}
}
return { value, oldValue, location: storageType };
}, [storageType, timestamp, count]);
const removeItem = useCallback((name) => {
if (hasSupport) {
storage.removeItem(name);
if (forceUpdate) {
updateCount(safeUpdateCount);
}
}
return storageType;
}, [storageType, timestamp, count]);
// cleanup ref to old object
useEffect(() => {
return () => {
options = {};
}
}, []);
return {
getItem,
setItem,
removeItem,
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment