useStorage
A React hook that uses localStorage (or sessionStorage) to persist component state.
import { useState } from 'react';
type UseStorage = <T>(
key: string,
initialState: T,
opts?: {
serialize?: typeof JSON.stringify;
deserialize?: typeof JSON.parse;
storage?: Storage;
}
) => [T, (newState: T) => void];
/**
* Storage wrapper around Reacts useState hook which persists any state in the
* browser using either localStorage (default) or sessionStorage.
*
* @param key used for storing data
* @param initialState initial value of state
* @param opts you can also use sessionStorage here
*
* Example usage:
* ```tsx
* const [name, setName] = useStorage('app.name', '')
*
* // in component use:
* // setName(value)
* ```
*
* Or with sessionStorage:
* ```tsx
* const [name, setName] = useStorage('app.name', 'Koen van Gilst', { storage: window.sessionStorage })
* ```
*
*/
export const useStorage: UseStorage = (
key,
initialState,
{
serialize = JSON.stringify,
deserialize = JSON.parse,
storage = localStorage // you can also use sessionStorage
} = {}
) => {
const [state, setState] = useState(() => {
// make sure we're not running this on the server
if (typeof window === 'undefined') {
return initialState;
}
try {
const valueInStorage = storage.getItem(key);
// if value was stored earlier, use that as initial state for useState
if (valueInStorage) {
return deserialize(valueInStorage);
}
// nothing saved in storage yet, store initialState from options
storage.setItem(key, serialize(initialState));
} catch (error) {
// logs to the console, or use some error reporting tool here
console.error(error);
}
// use initial state from options to initialize
return initialState;
});
// if component updates state, make sure we also try to store it
// in our storage, and update the state after that
const storeState = (newState: typeof initialState) => {
try {
storage.setItem(key, serialize(newState));
} catch (error) {
console.error(error);
}
setState(newState);
};
return [state, storeState];
};