forked from github/plane
39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
import { useState, useEffect, useCallback } from "react";
|
|
|
|
const useLocalStorage = <T,>(
|
|
key: string,
|
|
initialValue?: T extends Function ? never : T | (() => T)
|
|
) => {
|
|
const [value, setValue] = useState<T | string>("");
|
|
|
|
useEffect(() => {
|
|
const data = window.localStorage.getItem(key);
|
|
if (data !== null && data !== "undefined") setValue(JSON.parse(data));
|
|
else setValue(typeof initialValue === "function" ? initialValue() : initialValue);
|
|
}, [key, initialValue]);
|
|
|
|
const updateState = useCallback(
|
|
(value: T) => {
|
|
if (!value) window.localStorage.removeItem(key);
|
|
else window.localStorage.setItem(key, JSON.stringify(value));
|
|
setValue(value);
|
|
window.dispatchEvent(new Event(`local-storage-change-${key}`));
|
|
},
|
|
[key]
|
|
);
|
|
|
|
const reHydrateState = useCallback(() => {
|
|
const data = window.localStorage.getItem(key);
|
|
if (data !== null) setValue(JSON.parse(data));
|
|
}, [key]);
|
|
|
|
useEffect(() => {
|
|
window.addEventListener(`local-storage-change-${key}`, reHydrateState);
|
|
return () => window.removeEventListener(`local-storage-change-${key}`, reHydrateState);
|
|
}, [reHydrateState, key]);
|
|
|
|
return [value, updateState];
|
|
};
|
|
|
|
export default useLocalStorage;
|