Skip to content

Instantly share code, notes, and snippets.

@coreyward
Created January 15, 2021 00:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coreyward/50e4a8c387ce476b362c2c6f128ad61f to your computer and use it in GitHub Desktop.
Save coreyward/50e4a8c387ce476b362c2c6f128ad61f to your computer and use it in GitHub Desktop.
Persisted useState hook backed by the Local Storage API
import { useState, useCallback, useEffect } from "react"
/**
* Similar to `useState` but with some lightweight behind-the-scenes
* writing to localStorage; also subscribes to changes in localStorage
*
* @param {string} key The string key name to be written to localStorage
* @param {object} options
* @param {*} options.initialValue Initial value for setState
* @param {boolean} options.bool Treat values as boolean types
* @returns
*/
const useStorage = (key, { initialValue, bool }) => {
const [value, setValue] = useState(initialValue)
useEffect(() => {
const rawValue = window.localStorage.getItem(key)
if (rawValue != null) setValue(bool ? parseRawValue(rawValue) : rawValue)
const handleChanges = (e) => {
if (e.key === key) {
setValue(bool ? parseRawValue(e.newValue) : e.newValue)
}
}
window.addEventListener("storage", handleChanges)
return () => {
window.removeEventListener("storage", handleChanges)
}
}, [key, bool])
const updater = useCallback(
(newValue) => {
setValue(newValue)
window.localStorage.setItem(key, newValue)
},
[key]
)
return [value, updater]
}
export default useStorage
const parseRawValue = (rawValue) =>
rawValue === "true" || rawValue === "1"
? true
: rawValue === "false" || rawValue === "0"
? false
: rawValue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment