UNPKG

rooks

Version:

Essential React custom hooks ⚓ to super charge your components!

142 lines (141 loc) 5.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useSessionstorageState = void 0; var react_1 = require("react"); function getValueFromSessionStorage(key) { var _a; if (typeof sessionStorage === "undefined") { return null; } var storedValue = (_a = sessionStorage.getItem(key)) !== null && _a !== void 0 ? _a : "null"; try { return JSON.parse(storedValue); } catch (error) { console.error(error); } return storedValue; } function saveValueToSessionStorage(key, value) { if (typeof sessionStorage === "undefined") { return null; } return sessionStorage.setItem(key, JSON.stringify(value)); } /** * @param key Key of the sessionStorage object * @param initialState Default initial value */ function initialize(key, initialState) { var valueLoadedFromSessionStorage = getValueFromSessionStorage(key); if (valueLoadedFromSessionStorage === null) { return initialState; } else { return valueLoadedFromSessionStorage; } } /** * useSessionstorageState hook * Tracks a value within sessionStorage and updates it * * @param {string} key - Key of the sessionStorage object * @param {any} initialState - Default initial value * @returns {[any, Dispatch<SetStateAction<any>>, () => void]} * @see https://react-hooks.org/docs/useSessionstorageState */ function useSessionstorageState(key, initialState) { var _a = (0, react_1.useState)(function () { return initialize(key, initialState); }), value = _a[0], setValue = _a[1]; var isUpdateFromCrossDocumentListener = (0, react_1.useRef)(false); var isUpdateFromWithinDocumentListener = (0, react_1.useRef)(false); var customEventTypeName = (0, react_1.useMemo)(function () { return "rooks-".concat(key, "-sessionstorage-update"); }, [key]); (0, react_1.useEffect)(function () { /** * We need to ensure there is no loop of * storage events fired. Hence we are using a ref * to keep track of whether setValue is from another * storage event */ if (!isUpdateFromCrossDocumentListener.current) { saveValueToSessionStorage(key, value); } }, [key, value]); var listenToCrossDocumentStorageEvents = (0, react_1.useCallback)(function (event) { var _a; if (event.storageArea === sessionStorage && event.key === key) { try { isUpdateFromCrossDocumentListener.current = true; var newValue = JSON.parse((_a = event.newValue) !== null && _a !== void 0 ? _a : "null"); if (value !== newValue) { setValue(newValue); } } catch (error) { console.log(error); } } }, [key, value]); // check for changes across windows (0, react_1.useEffect)(function () { // eslint-disable-next-line no-negated-condition if (typeof window !== "undefined") { window.addEventListener("storage", listenToCrossDocumentStorageEvents); return function () { window.removeEventListener("storage", listenToCrossDocumentStorageEvents); }; } else { console.warn("[useSessionstorageState] window is undefined."); return function () { }; } }, [listenToCrossDocumentStorageEvents]); var listenToCustomEventWithinDocument = (0, react_1.useCallback)(function (event) { try { isUpdateFromWithinDocumentListener.current = true; var newValue = event.detail.newValue; if (value !== newValue) { setValue(newValue); } } catch (error) { console.log(error); } }, [value]); // check for changes within document (0, react_1.useEffect)(function () { // eslint-disable-next-line no-negated-condition if (typeof document !== "undefined") { document.addEventListener(customEventTypeName, listenToCustomEventWithinDocument); return function () { document.removeEventListener(customEventTypeName, listenToCustomEventWithinDocument); }; } else { console.warn("[useSessionstorageState] document is undefined."); return function () { }; } }, [customEventTypeName, listenToCustomEventWithinDocument]); var broadcastValueWithinDocument = (0, react_1.useCallback)(function (newValue) { // eslint-disable-next-line no-negated-condition if (typeof document !== "undefined") { var event_1 = new CustomEvent(customEventTypeName, { detail: { newValue: newValue } }); document.dispatchEvent(event_1); } else { console.warn("[useSessionstorageState] document is undefined."); } }, [customEventTypeName]); var set = (0, react_1.useCallback)(function (newValue) { isUpdateFromCrossDocumentListener.current = false; isUpdateFromWithinDocumentListener.current = false; setValue(newValue); broadcastValueWithinDocument(newValue); }, [broadcastValueWithinDocument]); var remove = (0, react_1.useCallback)(function () { sessionStorage.removeItem(key); }, [key]); return [value, set, remove]; } exports.useSessionstorageState = useSessionstorageState;