Last active
February 24, 2021 07:14
-
-
Save ravid7000/6a99a5efc18011b3e3bb4303edf1b73a to your computer and use it in GitHub Desktop.
This file contains 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 { 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