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];
};

View File

@@ -12,10 +12,16 @@ import { getEndBlock } from "../../utils/getEndBlock";
import type { PoolListingQuery } from "./__generated__/PoolListingQuery.graphql";
import { notEmpty } from "../../utils/notEmpty";
import { Spinner } from "../../components";
import { usePersistedState } from "../../hooks/usePersistedState";
export const PoolListing = () => {
const { provider } = useBsc();
const [validPools, setValidPools] = useState<PoolConfig[]>([]);
const [validPools, setValidPools] = usePersistedState<PoolConfig[]>(
"validPools",
[],
1200000 // 20 minutes
);
const [isLoadingPools, setIsLoadingPools] = useState(true);
const { currentUser } = useLazyLoadQuery<PoolListingQuery>(
@@ -35,6 +41,8 @@ export const PoolListing = () => {
useEffect(() => {
(async () => {
if (validPools.length) return;
const blockNumber = await provider.getBlockNumber();
const getChef = (pool: PoolConfig) => {
@@ -67,9 +75,9 @@ export const PoolListing = () => {
setValidPools(pools.filter(notEmpty));
});
})();
}, [provider]);
}, [provider, setValidPools, validPools.length]);
if (isLoadingPools) {
if (isLoadingPools && !validPools.length) {
return (
<div className="w-full grid place-items-center mt-12">
<Spinner />