add persisted state hook

This commit is contained in:
João Geonizeli
2021-08-31 11:30:05 -03:00
parent eb4273d20c
commit 933a6774f6
2 changed files with 69 additions and 3 deletions

View File

@@ -0,0 +1,58 @@
import type { SetStateAction, Dispatch } from "react";
import { useState, useEffect, useCallback } from "react";
export const usePersistedState = <S>(
key: string,
initialValue: S,
ttl?: number
): [S, Dispatch<SetStateAction<S>>] => {
type PersistedStatePaylaod = {
value: S;
expiry?: number;
};
const [state, setState] = useState<S>(() => {
try {
const localStorageRaw = localStorage.getItem(key);
if (localStorageRaw === null) return initialValue;
const payload: PersistedStatePaylaod = JSON.parse(localStorageRaw);
if (!payload.expiry) return payload.value;
const expired = new Date().getTime() > payload.expiry;
if (expired) return initialValue;
return payload.value;
} catch {
return initialValue;
}
});
const setLocalStorage = useCallback(
(value) => {
try {
const expiry = ttl ? new Date().getTime() + ttl : undefined;
const payload: PersistedStatePaylaod = { value, expiry };
localStorage.setItem(key, JSON.stringify(payload));
} catch {
localStorage.removeItem(key);
}
},
[key]
);
const setLocalStorageAndState: Dispatch<SetStateAction<S>> = (newState) => {
setLocalStorage(newState);
setState(newState);
};
useEffect(() => {
setLocalStorage(state);
}, [setLocalStorage, state]);
return [state, setLocalStorageAndState];
};