Created
July 14, 2021 16:45
-
-
Save jonasantonelli/8caf89ef4b8677a9c08acc12d53a1299 to your computer and use it in GitHub Desktop.
useLocalStorageState
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 React from 'react'; | |
/** | |
* Implement a replacement for useState which keeps values in the localStorage. | |
* | |
* The idea here is that all calls to use useState can be replaced with | |
* useLocalStorageState(key, initialValue) and implement the same behavior. | |
* | |
* The first time useLocalStorageState is called the value will be initialValue | |
* because nothing is stored in localStorage. | |
* | |
* Each time the user calls the setter (similar to useState) we need to trigger | |
* component re-render and save the updated value in localStorage. | |
* | |
* The next time we are called we should use the value from localStorage. | |
* | |
* We should support the following values stored in localStorage: | |
* | |
* string, number, object, array | |
* | |
* Note that we're using GitHub gists here because there's no compiler. Please | |
* make sure your code is fully formed, no edge case, clean, etc. | |
* | |
* We're not worried about small issues like imports. The main issue is that the | |
* code is free of bugs and high quality. | |
* | |
* @param key The key should be the key used by localStorage | |
* @param initialValue The initial value to store for the first value. | |
*/ | |
export function useLocalStorageState<V>(key: string, initialValue: V) { | |
const [state, setState] = React.useState(() => { | |
const valueInLocalStorage = window.localStorage.getItem(key) | |
if (valueInLocalStorage) { | |
try { | |
return JSON.parse(valueInLocalStorage) | |
} catch (error) { | |
window.localStorage.removeItem(key) | |
} | |
} | |
return typeof initialValue === 'function' ? initialValue() : initialValue | |
}) | |
const prevKeyRef = React.useRef(key) | |
React.useEffect(() => { | |
const prevKey = prevKeyRef.current | |
if (prevKey !== key) { | |
window.localStorage.removeItem(prevKey) | |
} | |
prevKeyRef.current = key | |
if (state !== null || state !== undefined) { | |
window.localStorage.setItem(key, JSON.stringify(state)) | |
} | |
}, [key, state]) | |
return [state, setState] | |
} | |
export const RememberPassword = () => { | |
// TODO: change this to use useLocalStorageState | |
const [value, setValue] = useLocalStorageState('password', '') | |
return ( | |
<input type="checkbox" | |
value={value} | |
onChange={event => setValue(event.currentTarget.value)}/> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment