Last active
June 7, 2023 11:01
-
-
Save augustolazaro/a7c6fdbf4ec021ecc237aa36ad47202d to your computer and use it in GitHub Desktop.
React hook to manage local storage changes
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' | |
const originalSetItem = localStorage.setItem | |
localStorage.setItem = function() { | |
const event = new Event('storageChange') | |
document.dispatchEvent(event) | |
originalSetItem.apply(this, arguments) | |
} | |
const originalRemoveItem = localStorage.removeItem | |
localStorage.removeItem = function() { | |
const event = new Event('storageChange') | |
document.dispatchEvent(event) | |
originalRemoveItem.apply(this, arguments) | |
} | |
function useLocalStorage(key: string) { | |
const storageItem = localStorage.getItem(key) | |
const [storedValue, setValue] = React.useState( | |
!!storageItem ? JSON.parse(storageItem) : null | |
) | |
const setLocalItem = () => { | |
/** local storage update is not that fast */ | |
/** it makes sure that we are getting the new value */ | |
setTimeout(() => { | |
const itemValueFromStorage = localStorage.getItem(key) | |
const value = itemValueFromStorage && JSON.parse(itemValueFromStorage) | |
setValue(value) | |
}, 50) | |
} | |
const setStoredValue = (value: string | object) => { | |
const parsedValue = typeof value === 'object' ? JSON.stringify(value) : value | |
localStorage.setItem(key, parsedValue) | |
} | |
React.useEffect(() => { | |
document.addEventListener( | |
'storageChange', | |
setLocalItem, | |
false | |
) | |
return () => document.removeEventListener('storageChange', setLocalItem) | |
}, []) | |
return { storedValue, setStoredValue } | |
} | |
export default useLocalStorage |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You'll need define the
setTimeout
handler in the useEffect hook and return an unsubscribe function that callsclearTimeout
. As written, this will continue to run the timer after a component that uses the hook is unmounted, potentially resulting in runtime errors.