Last active
November 4, 2021 06:36
-
-
Save mjackson/f2ab605e3cb13ab069059d169cdc093a to your computer and use it in GitHub Desktop.
A React hook for persisting state between page refreshes (also SSR compatible)
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 { useEffect, useRef } from 'react'; | |
function getItem(storage, key) { | |
const value = storage.getItem(key); | |
if (!value) return null; | |
try { | |
return JSON.parse(value); | |
} catch (error) { | |
return null; | |
} | |
} | |
function setItem(storage, key, value) { | |
storage.setItem(key, JSON.stringify(value)); | |
} | |
/** | |
* A wrapper for useState that retrieves the initial state from a | |
* WebStorage object and saves the state there as it changes. | |
*/ | |
export default function useStorage(storage, key, [state, setState]) { | |
const checkStorageRef = useRef(true); | |
// Check for an existing value on the initial render... | |
if (checkStorageRef.current) { | |
checkStorageRef.current = false; | |
const storedState = getItem(storage, key); | |
if (storedState) setState(storedState); | |
} | |
useEffect(() => { | |
setItem(storage, key, state); | |
}, [storage, key, state]); | |
return [state, setState]; | |
} | |
/** | |
* A convenient wrapper for useStorage(window.localStorage, ...) | |
*/ | |
export function useLocalStorage(key, state) { | |
return useStorage(getStorage('localStorage'), key, state); | |
} | |
/** | |
* A convenient wrapper for useStorage(window.sessionStorage, ...) | |
*/ | |
export function useSessionStorage(key, state) { | |
return useStorage(getStorage('sessionStorage'), key, state); | |
} | |
function getStorage(name) { | |
return typeof window === 'object' && window[name] | |
? window[name] | |
: createMemoryStorage(); | |
} | |
function createMemoryStorage() { | |
const storage = {}; | |
return { | |
getItem(key) { | |
return storage[key]; | |
}, | |
setItem(key, value) { | |
storage[key] = value; | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment