diff --git a/src/lib/web3/hooks/useIndexer.ts b/src/lib/web3/hooks/useIndexer.ts index f5737b714..85fd33fe7 100644 --- a/src/lib/web3/hooks/useIndexer.ts +++ b/src/lib/web3/hooks/useIndexer.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import useSWRSubscription, { SWRSubscription } from 'swr/subscription'; const { REACT_APP__INDEXER_API = '' } = process.env; @@ -265,9 +265,8 @@ export class IndexerStreamAccumulateDualDataSet< } interface StaleWhileRevalidateState { - data: DataSetOrDataSets | undefined; - isValidating: boolean; - error: Error | undefined; + data?: DataSetOrDataSets; + error?: Error; } // add higher-level hook to stream real-time DataSet or DataSets of Indexer URL function useIndexerStream< @@ -288,34 +287,30 @@ function useIndexerStream< DataRow extends BaseDataRow, DataSet = BaseDataSet >( - url: URL | string | undefined, + url: URL | string = '', IndexerClass: | typeof IndexerStreamAccumulateSingleDataSet | typeof IndexerStreamAccumulateDualDataSet ): StaleWhileRevalidateState { - const [dataset, setDataSet] = useState(); - const [isValidating, setIsValidating] = useState(false); - const [error, setError] = useState(); - - // todo: use deep-compare effect to not cause unneccessary updates from url or opts - useEffect(() => { - if (url) { - setIsValidating(true); - const stream = new IndexerClass(url, { - onAccumulated: (dataSet) => { - // note: the TypeScript here is a bit hacky but this should be ok - setDataSet(dataSet as unknown as DataSet | DataSet[]); - }, - onCompleted: () => setIsValidating(false), - onError: (error) => setError(error), - }); - return () => { - stream.unsubscribe(); - }; - } - }, [IndexerClass, url]); + // define subscription callback which may or may not be used in this component + // it is passed to useSWRSubscription to handle if the subscription should be + // created/held/destroyed as multiple components may listen for the same data + const subscribe: SWRSubscription = ( + url, + { next } + ) => { + const stream = new IndexerClass(url, { + onAccumulated: (dataSet) => { + // note: the TypeScript here is a bit hacky but this should be ok + next(null, dataSet as unknown as DataSet | DataSet[]); + }, + onError: (error) => next(error), + }); + return () => stream.unsubscribe(); + }; - return { data: dataset, isValidating, error }; + // return cached subscription data + return useSWRSubscription(`${url}`, subscribe); } // higher-level hook to stream real-time DataSet of Indexer URL diff --git a/src/lib/web3/hooks/useTokenPairs.ts b/src/lib/web3/hooks/useTokenPairs.ts index bed3b68d4..13d10d199 100644 --- a/src/lib/web3/hooks/useTokenPairs.ts +++ b/src/lib/web3/hooks/useTokenPairs.ts @@ -12,12 +12,11 @@ type DataRow = [index: number, values: TokenPairReserves]; type TokenPairsState = { data: TokenPairReserves[] | undefined; - isValidating: boolean; error: Error | null; }; export default function useTokenPairs(): TokenPairsState { - const { data, isValidating, error } = + const { data, error } = useIndexerStreamOfSingleDataSet('/liquidity/pairs'); const values: TokenPairReserves[] | undefined = useMemo(() => { @@ -30,7 +29,7 @@ export default function useTokenPairs(): TokenPairsState { }, [data]); // return state - return { data: values, isValidating, error: error || null }; + return { data: values, error: error || null }; } // add convenience method to fetch ticks in a pair