Skip to content

Instantly share code, notes, and snippets.

@jonasantonelli
Created July 14, 2021 16:45
Show Gist options
  • Save jonasantonelli/8caf89ef4b8677a9c08acc12d53a1299 to your computer and use it in GitHub Desktop.
Save jonasantonelli/8caf89ef4b8677a9c08acc12d53a1299 to your computer and use it in GitHub Desktop.
useLocalStorageState
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