UNPKG

@modern-kit/react

Version:
99 lines (94 loc) 3.29 kB
'use strict'; var utils = require('@modern-kit/utils'); var React = require('react'); var hooksUseVisibilityChange = require('../useVisibilityChange/index.cjs'); require('../useEventListener/index.cjs'); require('../usePreservedCallback/index.cjs'); require('../useIsomorphicLayoutEffect/index.cjs'); const CUSTOM_EVENT_KEYS = "modern-kit-local-storage"; const localStorageEventHandler = { key: CUSTOM_EVENT_KEYS, subscribe: (callback) => { window.addEventListener(CUSTOM_EVENT_KEYS, callback); }, unsubscribe: (callback) => { window.removeEventListener(CUSTOM_EVENT_KEYS, callback); }, dispatchEvent: () => { window.dispatchEvent(new StorageEvent(CUSTOM_EVENT_KEYS)); } }; const getSnapshot = (key) => { try { return window.localStorage.getItem(key); } catch { return null; } }; const getServerSnapshot = (initialValue) => { return JSON.stringify(initialValue); }; const subscribe = (callback) => { localStorageEventHandler.subscribe(callback); return () => { localStorageEventHandler.unsubscribe(callback); }; }; const getParsedState = (state, fallbackValue) => { if (state == null) { return fallbackValue; } return utils.parseJSON(state); }; const storageManager = new utils.StorageManager("localStorage"); function useLocalStorage(options) { const { key, visibilityChange = false } = options; const initialValue = "initialValue" in options ? options.initialValue : null; const initialValueToUse = React.useMemo(() => { return utils.isFunction(initialValue) ? initialValue() : initialValue; }, [initialValue]); const externalStoreState = React.useSyncExternalStore( subscribe, () => getSnapshot(key), () => getServerSnapshot(initialValueToUse) ); const state = React.useMemo(() => { return getParsedState(externalStoreState, initialValueToUse); }, [externalStoreState, initialValueToUse]); const setState = React.useCallback( (value) => { try { const prevStateString = getSnapshot(key); const prevState = getParsedState(prevStateString, initialValueToUse); const valueToUse = utils.isFunction(value) ? value(prevState) : value; storageManager.setItem(key, valueToUse); localStorageEventHandler.dispatchEvent(); } catch (err) { throw new Error( `\uB85C\uCEEC \uC2A4\uD1A0\uB9AC\uC9C0 "${key}" key\uC5D0 \uB370\uC774\uD130\uB97C \uC800\uC7A5\uD558\uB294\uB370 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4: ${err}` ); } }, [key, initialValueToUse] ); const removeState = React.useCallback(() => { try { storageManager.removeItem(key); localStorageEventHandler.dispatchEvent(); } catch (err) { throw new Error( `\uB85C\uCEEC \uC2A4\uD1A0\uB9AC\uC9C0 "${key}" key\uC758 \uB370\uC774\uD130\uB97C \uC0AD\uC81C\uD558\uB294\uB370 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4: ${err}` ); } }, [key]); const handleVisibilityChange = React.useCallback(() => { localStorageEventHandler.dispatchEvent(); }, []); hooksUseVisibilityChange.useVisibilityChange({ onShow: handleVisibilityChange, enabled: visibilityChange }); return { state, setState, removeState }; } exports.useLocalStorage = useLocalStorage; //# sourceMappingURL=index.cjs.map