@modern-kit/react
Version:
99 lines (94 loc) • 3.29 kB
JavaScript
;
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