2020-03-16 13:29:15 -04:00
|
|
|
import { useState, useEffect } from 'react';
|
2019-06-11 14:10:58 -04:00
|
|
|
|
2020-04-30 22:07:20 -07:00
|
|
|
const listeners = {};
|
|
|
|
|
|
|
|
function getSetAllValues(key, setValue) {
|
|
|
|
if (!key) {
|
|
|
|
// If no key just return the normal setValue function
|
|
|
|
return setValue;
|
|
|
|
}
|
|
|
|
return value => listeners[key].forEach(fn => fn(value));
|
|
|
|
}
|
|
|
|
|
2019-06-11 14:10:58 -04:00
|
|
|
export default function usePersistedState(key, firstTimeDefault) {
|
|
|
|
// If no key is passed in, act as a normal `useState`
|
|
|
|
let defaultValue;
|
2019-12-30 14:54:53 -05:00
|
|
|
let localStorageAvailable;
|
2020-04-30 22:07:20 -07:00
|
|
|
|
2019-12-30 14:54:53 -05:00
|
|
|
try {
|
|
|
|
localStorageAvailable = Boolean(window.localStorage);
|
|
|
|
} catch (e) {
|
|
|
|
localStorageAvailable = false;
|
|
|
|
}
|
|
|
|
if (key && localStorageAvailable) {
|
2019-08-13 01:35:13 -04:00
|
|
|
let item = localStorage.getItem(key);
|
|
|
|
|
|
|
|
if (item) {
|
|
|
|
let parsedItem;
|
|
|
|
try {
|
|
|
|
parsedItem = JSON.parse(item);
|
|
|
|
} catch (e) {}
|
|
|
|
|
2019-08-14 22:50:41 -04:00
|
|
|
if (parsedItem !== undefined) {
|
2019-08-13 01:35:13 -04:00
|
|
|
defaultValue = parsedItem;
|
|
|
|
} else {
|
|
|
|
defaultValue = item;
|
|
|
|
}
|
2019-06-26 19:59:27 -04:00
|
|
|
}
|
2019-06-11 14:10:58 -04:00
|
|
|
}
|
|
|
|
|
2019-07-10 22:57:24 -04:00
|
|
|
if (!defaultValue && defaultValue !== false) {
|
2019-06-11 14:10:58 -04:00
|
|
|
defaultValue = firstTimeDefault;
|
|
|
|
}
|
|
|
|
|
|
|
|
const [value, setValue] = useState(defaultValue);
|
|
|
|
|
2020-04-30 22:07:20 -07:00
|
|
|
if (key && !Array.isArray(listeners[key])) {
|
|
|
|
listeners[key] = [];
|
|
|
|
}
|
|
|
|
|
2020-03-16 13:29:15 -04:00
|
|
|
useEffect(() => {
|
|
|
|
if (key && localStorageAvailable) {
|
|
|
|
localStorage.setItem(key, typeof value === 'object' ? JSON.stringify(value) : value);
|
2019-06-11 14:10:58 -04:00
|
|
|
}
|
2020-04-30 22:07:20 -07:00
|
|
|
if (key) {
|
|
|
|
// add hook on mount
|
|
|
|
listeners[key].push(setValue);
|
|
|
|
}
|
|
|
|
return () => {
|
|
|
|
if (key) {
|
|
|
|
// remove hook on unmount
|
|
|
|
listeners[key] = listeners[key].filter(listener => listener !== setValue);
|
|
|
|
}
|
|
|
|
};
|
2020-03-16 13:29:15 -04:00
|
|
|
}, [key, value, localStorageAvailable]);
|
2019-06-11 14:10:58 -04:00
|
|
|
|
2020-04-30 22:07:20 -07:00
|
|
|
return [value, getSetAllValues(key, setValue)];
|
2019-06-11 14:10:58 -04:00
|
|
|
}
|