react-localstorage-hooks
Version:
A collection of React hooks for reactively managing localStorage
50 lines (49 loc) • 2.38 kB
JavaScript
import { __assign } from "tslib";
import { useCallback, useEffect, useState } from 'react';
import { serialize, deserialize } from '../utils';
;
/**
* Hook to create reactive state variables on `localStorage`.
*
* @param key key for localStorage
* @param opts Options object
* @returns a pair of current state and `setState` method to update the state.
*/
function useLocalStorageState(key, opts) {
var options = __assign({ initialState: undefined, sync: true }, opts);
var _a = useState(function () { var _a; return typeof window !== 'undefined' ? (_a = deserialize(window.localStorage.getItem(key))) !== null && _a !== void 0 ? _a : options.initialState : options.initialState; }), state = _a[0], setState = _a[1];
var setStateWrapper = useCallback(function (newVal) {
if (typeof window === 'undefined')
return;
var result = newVal instanceof Function ? newVal(state) : newVal;
var serializedResult = serialize(result);
window.localStorage.setItem(key, serializedResult);
// storage event is also triggered by the script so that synced hooks in the same window get up-to-date values
var event = new StorageEvent('storage', { key: key, newValue: serializedResult });
window.dispatchEvent(event);
setState(result);
}, [key, setState, state]);
var handleStorage = useCallback(function (event) {
var _a;
if (event.key === key && deserialize(event.newValue) !== state) {
setState((_a = deserialize(event.newValue)) !== null && _a !== void 0 ? _a : options.initialState);
}
}, [state, key, setState]);
useEffect(function () {
if (options.sync && typeof window !== 'undefined') {
window.addEventListener('storage', handleStorage);
return function () { return window.removeEventListener('storage', handleStorage); };
}
return function () { };
}, [handleStorage, options.sync]);
useEffect(function () {
if (typeof window === 'undefined')
return;
var storedData = deserialize(window.localStorage.getItem(key));
if (storedData === null || storedData === undefined) {
window.localStorage.setItem(key, serialize(options.initialState));
}
}, [key]);
return [state, setStateWrapper];
}
export default useLocalStorageState;