Skip to content

Instantly share code, notes, and snippets.

@mjackson
Last active November 4, 2021 06:36
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mjackson/f2ab605e3cb13ab069059d169cdc093a to your computer and use it in GitHub Desktop.
Save mjackson/f2ab605e3cb13ab069059d169cdc093a to your computer and use it in GitHub Desktop.
A React hook for persisting state between page refreshes (also SSR compatible)
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