create-ls
Version:
A simple state manager for local storage in React applications.
118 lines (117 loc) • 4.48 kB
JavaScript
import { useCallback, useEffect, useState } from "react";
var checkLocalStorageAvailable = function () {
if (typeof window === "undefined")
return false;
try {
var testKey = "__storage_test__";
localStorage.setItem(testKey, testKey);
localStorage.removeItem(testKey);
return true;
}
catch (_a) {
return false;
}
};
var safeJSONParse = function (value) {
try {
var parsed = JSON.parse(value);
if (parsed === null || parsed === undefined)
return undefined;
return parsed;
}
catch (_a) {
return value;
}
};
var safeJSONStringify = function (value) {
if (typeof value === "string")
return value;
try {
return JSON.stringify(value);
}
catch (_a) {
return undefined;
}
};
var useFunction = function (name, initialValue) {
var _a = useState(function () {
if (!checkLocalStorageAvailable())
return initialValue || undefined;
var stored = localStorage.getItem(name);
if (!stored)
return initialValue || undefined;
return safeJSONParse(stored) || initialValue || undefined;
}), value = _a[0], setValue = _a[1];
var get = useCallback(function () { return value; }, [value]);
var set = useCallback(function (newValue) {
setValue(newValue);
if (!checkLocalStorageAvailable())
return;
var serialized = safeJSONStringify(newValue);
if (!serialized)
return;
localStorage.setItem(name, serialized);
window.dispatchEvent(new CustomEvent("localStorageChange", { detail: { key: name, newValue: serialized } }));
}, [name]);
var reset = useCallback(function () {
setValue(initialValue || undefined);
if (!checkLocalStorageAvailable())
return;
localStorage.removeItem(name);
window.dispatchEvent(new CustomEvent("localStorageChange", { detail: { key: name, newValue: undefined } }));
}, [name, initialValue]);
var hasValue = useCallback(function () { return value !== undefined && value !== null && value !== ""; }, [value]);
useEffect(function () {
if (!checkLocalStorageAvailable())
return;
var stored = localStorage.getItem(name);
if (!stored) {
var serialized = safeJSONStringify(initialValue);
if (!serialized)
return;
localStorage.setItem(name, serialized);
window.dispatchEvent(new CustomEvent("localStorageChange", { detail: { key: name, newValue: serialized } }));
return;
}
var parsed = safeJSONParse(stored);
if (parsed !== undefined && JSON.stringify(parsed) !== JSON.stringify(value)) {
setValue(parsed);
}
}, [name, initialValue, value]);
useEffect(function () {
if (!checkLocalStorageAvailable())
return;
var handleStorageChange = function (event) {
if (event instanceof StorageEvent) {
if (event.key === name) {
if (event.newValue === null) {
setValue(initialValue || undefined);
}
else {
var parsed = safeJSONParse(event.newValue);
if (parsed !== undefined && JSON.stringify(parsed) !== JSON.stringify(value)) {
setValue(parsed);
}
}
}
}
else if (event instanceof CustomEvent) {
var _a = event.detail, key = _a.key, newValue = _a.newValue;
if (key === name) {
var parsed = safeJSONParse(newValue);
if (parsed !== undefined && JSON.stringify(parsed) !== JSON.stringify(value)) {
setValue(parsed);
}
}
}
};
window.addEventListener("storage", handleStorageChange);
window.addEventListener("localStorageChange", handleStorageChange);
return function () {
window.removeEventListener("storage", handleStorageChange);
window.removeEventListener("localStorageChange", handleStorageChange);
};
}, [name, initialValue, value]);
return { get: get, set: set, reset: reset, hasValue: hasValue };
};
export { useFunction as createLS };