add persisted state hook
This commit is contained in:
58
app/javascript/src/hooks/usePersistedState.ts
Normal file
58
app/javascript/src/hooks/usePersistedState.ts
Normal 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];
|
||||||
|
};
|
||||||
@@ -12,10 +12,16 @@ import { getEndBlock } from "../../utils/getEndBlock";
|
|||||||
import type { PoolListingQuery } from "./__generated__/PoolListingQuery.graphql";
|
import type { PoolListingQuery } from "./__generated__/PoolListingQuery.graphql";
|
||||||
import { notEmpty } from "../../utils/notEmpty";
|
import { notEmpty } from "../../utils/notEmpty";
|
||||||
import { Spinner } from "../../components";
|
import { Spinner } from "../../components";
|
||||||
|
import { usePersistedState } from "../../hooks/usePersistedState";
|
||||||
|
|
||||||
export const PoolListing = () => {
|
export const PoolListing = () => {
|
||||||
const { provider } = useBsc();
|
const { provider } = useBsc();
|
||||||
const [validPools, setValidPools] = useState<PoolConfig[]>([]);
|
const [validPools, setValidPools] = usePersistedState<PoolConfig[]>(
|
||||||
|
"validPools",
|
||||||
|
[],
|
||||||
|
1200000 // 20 minutes
|
||||||
|
);
|
||||||
|
|
||||||
const [isLoadingPools, setIsLoadingPools] = useState(true);
|
const [isLoadingPools, setIsLoadingPools] = useState(true);
|
||||||
|
|
||||||
const { currentUser } = useLazyLoadQuery<PoolListingQuery>(
|
const { currentUser } = useLazyLoadQuery<PoolListingQuery>(
|
||||||
@@ -35,6 +41,8 @@ export const PoolListing = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
if (validPools.length) return;
|
||||||
|
|
||||||
const blockNumber = await provider.getBlockNumber();
|
const blockNumber = await provider.getBlockNumber();
|
||||||
|
|
||||||
const getChef = (pool: PoolConfig) => {
|
const getChef = (pool: PoolConfig) => {
|
||||||
@@ -67,9 +75,9 @@ export const PoolListing = () => {
|
|||||||
setValidPools(pools.filter(notEmpty));
|
setValidPools(pools.filter(notEmpty));
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
}, [provider]);
|
}, [provider, setValidPools, validPools.length]);
|
||||||
|
|
||||||
if (isLoadingPools) {
|
if (isLoadingPools && !validPools.length) {
|
||||||
return (
|
return (
|
||||||
<div className="w-full grid place-items-center mt-12">
|
<div className="w-full grid place-items-center mt-12">
|
||||||
<Spinner />
|
<Spinner />
|
||||||
|
|||||||
Reference in New Issue
Block a user