react-hook-session-web-storage
Version:
A React hook for accessing sessionStorage
154 lines (120 loc) • 5.96 kB
JavaScript
import { useState, useEffect, useCallback } from "react";
const isString = variable => typeof variable == "string" || variable instanceof String;
const clearObjectValues = object => Object.fromEntries(Object.entries(object).map(([key]) => [key, null]));
const safeObjectValues = object => Object.fromEntries(Object.entries(object).map(([key, value]) => [key, [undefined, null].includes(value) ? null : `${value}`]));
const updateObjectFromSessionStorage = object => {
let newValues = {};
let hasSomethingChanged = false;
for (const [key] of Object.entries(object)) {
var _sessionStorage, _sessionStorage$getIt;
const oldValue = object[key];
const newValue = (_sessionStorage = sessionStorage) === null || _sessionStorage === void 0 ? void 0 : (_sessionStorage$getIt = _sessionStorage.getItem) === null || _sessionStorage$getIt === void 0 ? void 0 : _sessionStorage$getIt.call(_sessionStorage, key);
if (newValue !== oldValue) {
var _sessionStorage2, _sessionStorage2$getI;
newValues = { ...newValues,
[key]: (_sessionStorage2 = sessionStorage) === null || _sessionStorage2 === void 0 ? void 0 : (_sessionStorage2$getI = _sessionStorage2.getItem) === null || _sessionStorage2$getI === void 0 ? void 0 : _sessionStorage2$getI.call(_sessionStorage2, key)
};
hasSomethingChanged = true;
}
}
if (!hasSomethingChanged) {
return false;
}
return newValues;
};
const useSessionStorage = (keys, {
syncFrequency = 0
} = {}) => {
const isUsingMultipleKeys = !isString(keys);
const initialValue = isUsingMultipleKeys ? clearObjectValues(keys) : null;
const [value, setValue] = useState(initialValue);
const readFromSessionStorage = useCallback(() => {
if (isUsingMultipleKeys) {
const newValues = updateObjectFromSessionStorage(value);
if (newValues) {
setValue({ ...value,
...newValues
});
return { ...value,
...newValues
};
}
return value;
} else {
var _sessionStorage3, _sessionStorage3$getI;
const oldValue = value;
const newValue = (_sessionStorage3 = sessionStorage) === null || _sessionStorage3 === void 0 ? void 0 : (_sessionStorage3$getI = _sessionStorage3.getItem) === null || _sessionStorage3$getI === void 0 ? void 0 : _sessionStorage3$getI.call(_sessionStorage3, keys);
if (newValue !== oldValue) {
setValue(newValue);
}
return newValue;
}
}, [isUsingMultipleKeys, keys, value]);
const writeToSessionStorage = useCallback(newValue => {
if (isUsingMultipleKeys) {
for (const [updatedKey, updatedValue] of Object.entries(newValue)) {
let safeUpdatedValue;
if ([undefined, null].includes(updatedValue)) {
var _sessionStorage4, _sessionStorage4$remo;
safeUpdatedValue = null;
(_sessionStorage4 = sessionStorage) === null || _sessionStorage4 === void 0 ? void 0 : (_sessionStorage4$remo = _sessionStorage4.removeItem) === null || _sessionStorage4$remo === void 0 ? void 0 : _sessionStorage4$remo.call(_sessionStorage4, updatedKey);
} else {
var _sessionStorage5, _sessionStorage5$setI;
safeUpdatedValue = `${updatedValue}`;
(_sessionStorage5 = sessionStorage) === null || _sessionStorage5 === void 0 ? void 0 : (_sessionStorage5$setI = _sessionStorage5.setItem) === null || _sessionStorage5$setI === void 0 ? void 0 : _sessionStorage5$setI.call(_sessionStorage5, updatedKey, safeUpdatedValue);
}
}
setValue(previousValue => {
return { ...previousValue,
...safeObjectValues(newValue)
};
});
} else {
let safeUpdatedValue;
if ([undefined, null].includes(newValue)) {
var _sessionStorage6, _sessionStorage6$remo;
safeUpdatedValue = null;
(_sessionStorage6 = sessionStorage) === null || _sessionStorage6 === void 0 ? void 0 : (_sessionStorage6$remo = _sessionStorage6.removeItem) === null || _sessionStorage6$remo === void 0 ? void 0 : _sessionStorage6$remo.call(_sessionStorage6, keys);
} else {
var _sessionStorage7, _sessionStorage7$setI;
safeUpdatedValue = `${newValue}`;
(_sessionStorage7 = sessionStorage) === null || _sessionStorage7 === void 0 ? void 0 : (_sessionStorage7$setI = _sessionStorage7.setItem) === null || _sessionStorage7$setI === void 0 ? void 0 : _sessionStorage7$setI.call(_sessionStorage7, keys, safeUpdatedValue);
}
setValue(safeUpdatedValue);
}
}, [isUsingMultipleKeys, keys]);
useEffect(() => {
const readSingleKeyFromSessionStorage = () => {
var _sessionStorage8, _sessionStorage8$getI;
const oldValue = value;
const newValue = (_sessionStorage8 = sessionStorage) === null || _sessionStorage8 === void 0 ? void 0 : (_sessionStorage8$getI = _sessionStorage8.getItem) === null || _sessionStorage8$getI === void 0 ? void 0 : _sessionStorage8$getI.call(_sessionStorage8, keys);
if (newValue !== oldValue) {
setValue(newValue);
}
};
const readMultipleKeysFromSessionStorage = () => {
const newValues = updateObjectFromSessionStorage(value);
if (newValues) {
setValue({ ...value,
...newValues
});
}
};
const readFromSessionStorage = isUsingMultipleKeys ? readMultipleKeysFromSessionStorage : readSingleKeyFromSessionStorage;
let readSessionStorageIntervalId;
readFromSessionStorage();
if (syncFrequency > 0) {
readSessionStorageIntervalId = setInterval(readFromSessionStorage, syncFrequency);
}
return () => {
if (syncFrequency > 0) {
clearInterval(readSessionStorageIntervalId);
}
};
}, [keys, value, isUsingMultipleKeys, syncFrequency]);
if (syncFrequency > 0) {
return [readFromSessionStorage, writeToSessionStorage];
}
return [value, writeToSessionStorage];
};
export default useSessionStorage;