fix: change top tokens query return type (#4453)
* query return * fix return * rm default empty string * rm ? * undef * undefined * null * fix * handle search * . * rebase * top tokens * rm blank * rm console log * make 100
This commit is contained in:
parent
0e530cf92e
commit
ac27c89a44
@ -7,8 +7,8 @@ import { Line } from '@visx/shape'
|
|||||||
import { filterTimeAtom } from 'components/Tokens/state'
|
import { filterTimeAtom } from 'components/Tokens/state'
|
||||||
import { bisect, curveBasis, NumberValue, scaleLinear } from 'd3'
|
import { bisect, curveBasis, NumberValue, scaleLinear } from 'd3'
|
||||||
import { useTokenPriceQuery } from 'graphql/data/TokenPriceQuery'
|
import { useTokenPriceQuery } from 'graphql/data/TokenPriceQuery'
|
||||||
|
import { TimePeriod } from 'graphql/data/TopTokenQuery'
|
||||||
import { useActiveLocale } from 'hooks/useActiveLocale'
|
import { useActiveLocale } from 'hooks/useActiveLocale'
|
||||||
import { TimePeriod } from 'hooks/useExplorePageQuery'
|
|
||||||
import { useAtom } from 'jotai'
|
import { useAtom } from 'jotai'
|
||||||
import { useCallback, useState } from 'react'
|
import { useCallback, useState } from 'react'
|
||||||
import { ArrowDownRight, ArrowUpRight } from 'react-feather'
|
import { ArrowDownRight, ArrowUpRight } from 'react-feather'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TimePeriod } from 'hooks/useExplorePageQuery'
|
import { TimePeriod } from 'graphql/data/TopTokenQuery'
|
||||||
import { useOnClickOutside } from 'hooks/useOnClickOutside'
|
import { useOnClickOutside } from 'hooks/useOnClickOutside'
|
||||||
import { useAtom } from 'jotai'
|
import { useAtom } from 'jotai'
|
||||||
import { useRef } from 'react'
|
import { useRef } from 'react'
|
||||||
|
@ -5,8 +5,8 @@ import { EventName } from 'components/AmplitudeAnalytics/constants'
|
|||||||
import SparklineChart from 'components/Charts/SparklineChart'
|
import SparklineChart from 'components/Charts/SparklineChart'
|
||||||
import CurrencyLogo from 'components/CurrencyLogo'
|
import CurrencyLogo from 'components/CurrencyLogo'
|
||||||
import { getChainInfo } from 'constants/chainInfo'
|
import { getChainInfo } from 'constants/chainInfo'
|
||||||
import { useCurrency, useToken } from 'hooks/Tokens'
|
import { TimePeriod, TokenData } from 'graphql/data/TopTokenQuery'
|
||||||
import { TimePeriod, TokenData } from 'hooks/useExplorePageQuery'
|
import { useCurrency } from 'hooks/Tokens'
|
||||||
import { useAtom } from 'jotai'
|
import { useAtom } from 'jotai'
|
||||||
import { useAtomValue } from 'jotai/utils'
|
import { useAtomValue } from 'jotai/utils'
|
||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
@ -245,6 +245,7 @@ const TokenName = styled.div`
|
|||||||
`
|
`
|
||||||
const TokenSymbol = styled(Cell)`
|
const TokenSymbol = styled(Cell)`
|
||||||
color: ${({ theme }) => theme.textTertiary};
|
color: ${({ theme }) => theme.textTertiary};
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
@media only screen and (max-width: ${SMALL_MEDIA_BREAKPOINT}) {
|
@media only screen and (max-width: ${SMALL_MEDIA_BREAKPOINT}) {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -443,10 +444,9 @@ export default function LoadedRow({
|
|||||||
tokenData: TokenData
|
tokenData: TokenData
|
||||||
timePeriod: TimePeriod
|
timePeriod: TimePeriod
|
||||||
}) {
|
}) {
|
||||||
const token = useToken(tokenAddress)
|
|
||||||
const currency = useCurrency(tokenAddress)
|
const currency = useCurrency(tokenAddress)
|
||||||
const tokenName = token?.name ?? ''
|
const tokenName = tokenData.name
|
||||||
const tokenSymbol = token?.symbol ?? ''
|
const tokenSymbol = tokenData.symbol
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const [favoriteTokens] = useAtom(favoritesAtom)
|
const [favoriteTokens] = useAtom(favoritesAtom)
|
||||||
const isFavorited = favoriteTokens.includes(tokenAddress)
|
const isFavorited = favoriteTokens.includes(tokenAddress)
|
||||||
@ -454,14 +454,14 @@ export default function LoadedRow({
|
|||||||
const filterString = useAtomValue(filterStringAtom)
|
const filterString = useAtomValue(filterStringAtom)
|
||||||
const filterNetwork = useAtomValue(filterNetworkAtom)
|
const filterNetwork = useAtomValue(filterNetworkAtom)
|
||||||
const L2Icon = getChainInfo(filterNetwork).circleLogoUrl
|
const L2Icon = getChainInfo(filterNetwork).circleLogoUrl
|
||||||
const delta = tokenData.percentChange[timePeriod]?.value
|
const delta = tokenData.percentChange?.[timePeriod]?.value
|
||||||
const arrow = delta ? getDeltaArrow(delta) : null
|
const arrow = delta ? getDeltaArrow(delta) : null
|
||||||
const formattedDelta = delta ? formatDelta(delta) : null
|
const formattedDelta = delta ? formatDelta(delta) : null
|
||||||
|
|
||||||
const exploreTokenSelectedEventProperties = {
|
const exploreTokenSelectedEventProperties = {
|
||||||
chain_id: filterNetwork,
|
chain_id: filterNetwork,
|
||||||
token_address: tokenAddress,
|
token_address: tokenAddress,
|
||||||
token_symbol: token?.symbol,
|
token_symbol: tokenSymbol,
|
||||||
token_list_index: tokenListIndex,
|
token_list_index: tokenListIndex,
|
||||||
token_list_length: tokenListLength,
|
token_list_length: tokenListLength,
|
||||||
time_frame: timePeriod,
|
time_frame: timePeriod,
|
||||||
|
@ -6,8 +6,7 @@ import {
|
|||||||
sortCategoryAtom,
|
sortCategoryAtom,
|
||||||
sortDirectionAtom,
|
sortDirectionAtom,
|
||||||
} from 'components/Tokens/state'
|
} from 'components/Tokens/state'
|
||||||
import { useAllTokens } from 'hooks/Tokens'
|
import { TimePeriod, TokenData } from 'graphql/data/TopTokenQuery'
|
||||||
import { TimePeriod, TokenData } from 'hooks/useExplorePageQuery'
|
|
||||||
import { useAtomValue } from 'jotai/utils'
|
import { useAtomValue } from 'jotai/utils'
|
||||||
import { ReactNode, Suspense, useCallback, useMemo } from 'react'
|
import { ReactNode, Suspense, useCallback, useMemo } from 'react'
|
||||||
import { AlertTriangle } from 'react-feather'
|
import { AlertTriangle } from 'react-feather'
|
||||||
@ -47,34 +46,33 @@ const TokenRowsContainer = styled.div`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`
|
`
|
||||||
|
|
||||||
function useFilteredTokens(addresses: string[]) {
|
function useFilteredTokens(tokens: TokenData[] | undefined) {
|
||||||
const filterString = useAtomValue(filterStringAtom)
|
const filterString = useAtomValue(filterStringAtom)
|
||||||
const favoriteTokens = useAtomValue(favoritesAtom)
|
const favoriteTokenAddresses = useAtomValue(favoritesAtom)
|
||||||
const showFavorites = useAtomValue(showFavoritesAtom)
|
const showFavorites = useAtomValue(showFavoritesAtom)
|
||||||
const shownTokens = showFavorites ? favoriteTokens : addresses
|
const shownTokens =
|
||||||
const allTokens = useAllTokens()
|
showFavorites && tokens ? tokens.filter((token) => favoriteTokenAddresses.includes(token.address)) : tokens
|
||||||
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() =>
|
() =>
|
||||||
shownTokens.filter((tokenAddress) => {
|
(shownTokens ?? []).filter((token) => {
|
||||||
const token = allTokens[tokenAddress]
|
if (!token.address) {
|
||||||
const tokenName = token?.name ?? ''
|
return false
|
||||||
const tokenSymbol = token?.symbol ?? ''
|
}
|
||||||
|
|
||||||
if (!filterString) {
|
if (!filterString) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
const lowercaseFilterString = filterString.toLowerCase()
|
const lowercaseFilterString = filterString.toLowerCase()
|
||||||
const addressIncludesFilterString = tokenAddress.toLowerCase().includes(lowercaseFilterString)
|
const addressIncludesFilterString = token?.address?.toLowerCase().includes(lowercaseFilterString)
|
||||||
const nameIncludesFilterString = tokenName.toLowerCase().includes(lowercaseFilterString)
|
const nameIncludesFilterString = token?.name?.toLowerCase().includes(lowercaseFilterString)
|
||||||
const symbolIncludesFilterString = tokenSymbol.toLowerCase().includes(lowercaseFilterString)
|
const symbolIncludesFilterString = token?.symbol?.toLowerCase().includes(lowercaseFilterString)
|
||||||
return nameIncludesFilterString || symbolIncludesFilterString || addressIncludesFilterString
|
return nameIncludesFilterString || symbolIncludesFilterString || addressIncludesFilterString
|
||||||
}),
|
}),
|
||||||
[allTokens, shownTokens, filterString]
|
[shownTokens, filterString]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function useSortedTokens(addresses: string[], tokenData: Record<string, TokenData> | null) {
|
function useSortedTokens(tokenData: TokenData[] | null) {
|
||||||
const sortCategory = useAtomValue(sortCategoryAtom)
|
const sortCategory = useAtomValue(sortCategoryAtom)
|
||||||
const sortDirection = useAtomValue(sortDirectionAtom)
|
const sortDirection = useAtomValue(sortDirectionAtom)
|
||||||
const timePeriod = useAtomValue<TimePeriod>(filterTimeAtom)
|
const timePeriod = useAtomValue<TimePeriod>(filterTimeAtom)
|
||||||
@ -93,40 +91,38 @@ function useSortedTokens(addresses: string[], tokenData: Record<string, TokenDat
|
|||||||
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() =>
|
() =>
|
||||||
addresses.sort((token1Address, token2Address) => {
|
tokenData &&
|
||||||
|
tokenData.sort((token1, token2) => {
|
||||||
if (!tokenData) {
|
if (!tokenData) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
// fix any, delta property
|
// fix delta/percent change property
|
||||||
const token1 = tokenData[token1Address] as any
|
|
||||||
const token2 = tokenData[token2Address] as any
|
|
||||||
|
|
||||||
if (!token1 || !token2 || !sortDirection || !sortCategory) {
|
if (!token1 || !token2 || !sortDirection || !sortCategory) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
let a: number
|
let a: number | null | undefined
|
||||||
let b: number
|
let b: number | null | undefined
|
||||||
switch (sortCategory) {
|
switch (sortCategory) {
|
||||||
case Category.marketCap:
|
case Category.marketCap:
|
||||||
a = token1.marketCap
|
a = token1.marketCap?.value
|
||||||
b = token2.marketCap
|
b = token2.marketCap?.value
|
||||||
break
|
|
||||||
case Category.percentChange:
|
|
||||||
a = token1.delta
|
|
||||||
b = token2.delta
|
|
||||||
break
|
break
|
||||||
case Category.price:
|
case Category.price:
|
||||||
a = token1.price
|
a = token1.price?.value
|
||||||
b = token2.price
|
b = token2.price?.value
|
||||||
break
|
break
|
||||||
case Category.volume:
|
case Category.volume:
|
||||||
a = token1.volume[timePeriod]
|
a = token1.volume?.[timePeriod]?.value
|
||||||
b = token2.volume[timePeriod]
|
b = token2.volume?.[timePeriod]?.value
|
||||||
|
break
|
||||||
|
case Category.percentChange:
|
||||||
|
a = token1.percentChange?.[timePeriod]?.value
|
||||||
|
b = token2.percentChange?.[timePeriod]?.value
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return sortFn(a, b)
|
return sortFn(a, b)
|
||||||
}),
|
}),
|
||||||
[addresses, tokenData, sortDirection, sortCategory, sortFn, timePeriod]
|
[tokenData, sortDirection, sortCategory, sortFn, timePeriod]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,12 +148,11 @@ export function LoadingTokenTable() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TokenTable({ data }: { data: Record<string, TokenData> | null }) {
|
export default function TokenTable({ data }: { data: TokenData[] | undefined }) {
|
||||||
const showFavorites = useAtomValue<boolean>(showFavoritesAtom)
|
const showFavorites = useAtomValue<boolean>(showFavoritesAtom)
|
||||||
const timePeriod = useAtomValue<TimePeriod>(filterTimeAtom)
|
const timePeriod = useAtomValue<TimePeriod>(filterTimeAtom)
|
||||||
const topTokenAddresses = data ? Object.keys(data) : []
|
const filteredTokens = useFilteredTokens(data)
|
||||||
const filteredTokens = useFilteredTokens(topTokenAddresses)
|
const sortedFilteredTokens = useSortedTokens(filteredTokens)
|
||||||
const filteredAndSortedTokens = useSortedTokens(filteredTokens, data)
|
|
||||||
|
|
||||||
/* loading and error state */
|
/* loading and error state */
|
||||||
if (data === null) {
|
if (data === null) {
|
||||||
@ -173,11 +168,11 @@ export default function TokenTable({ data }: { data: Record<string, TokenData> |
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showFavorites && filteredAndSortedTokens.length === 0) {
|
if (showFavorites && sortedFilteredTokens?.length === 0) {
|
||||||
return <NoTokensState message="You have no favorited tokens" />
|
return <NoTokensState message="You have no favorited tokens" />
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!showFavorites && filteredAndSortedTokens.length === 0) {
|
if (!showFavorites && sortedFilteredTokens?.length === 0) {
|
||||||
return <NoTokensState message="No tokens found" />
|
return <NoTokensState message="No tokens found" />
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,13 +181,13 @@ export default function TokenTable({ data }: { data: Record<string, TokenData> |
|
|||||||
<GridContainer>
|
<GridContainer>
|
||||||
<HeaderRow />
|
<HeaderRow />
|
||||||
<TokenRowsContainer>
|
<TokenRowsContainer>
|
||||||
{filteredAndSortedTokens.map((tokenAddress, index) => (
|
{sortedFilteredTokens?.map((token, index) => (
|
||||||
<LoadedRow
|
<LoadedRow
|
||||||
key={tokenAddress}
|
key={token.address}
|
||||||
tokenAddress={tokenAddress}
|
tokenAddress={token.address}
|
||||||
tokenListIndex={index}
|
tokenListIndex={index}
|
||||||
tokenListLength={filteredAndSortedTokens.length}
|
tokenListLength={sortedFilteredTokens.length}
|
||||||
tokenData={data[tokenAddress]}
|
tokenData={token}
|
||||||
timePeriod={timePeriod}
|
timePeriod={timePeriod}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { SupportedChainId } from 'constants/chains'
|
import { SupportedChainId } from 'constants/chains'
|
||||||
import { TimePeriod } from 'hooks/useExplorePageQuery'
|
import { TimePeriod } from 'graphql/data/TopTokenQuery'
|
||||||
import { atom, useAtom } from 'jotai'
|
import { atom, useAtom } from 'jotai'
|
||||||
import { atomWithReset, atomWithStorage } from 'jotai/utils'
|
import { atomWithReset, atomWithStorage } from 'jotai/utils'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import graphql from 'babel-plugin-relay/macro'
|
import graphql from 'babel-plugin-relay/macro'
|
||||||
import { TimePeriod } from 'hooks/useExplorePageQuery'
|
|
||||||
import { useLazyLoadQuery } from 'react-relay'
|
import { useLazyLoadQuery } from 'react-relay'
|
||||||
|
|
||||||
import type { Chain, TokenPriceQuery as TokenPriceQueryType } from './__generated__/TokenPriceQuery.graphql'
|
import type { Chain, TokenPriceQuery as TokenPriceQueryType } from './__generated__/TokenPriceQuery.graphql'
|
||||||
|
import { TimePeriod } from './TopTokenQuery'
|
||||||
|
|
||||||
export function useTokenPriceQuery(address: string, timePeriod: TimePeriod, chain: Chain) {
|
export function useTokenPriceQuery(address: string, timePeriod: TimePeriod, chain: Chain) {
|
||||||
const tokenPrices = useLazyLoadQuery<TokenPriceQueryType>(
|
const tokenPrices = useLazyLoadQuery<TokenPriceQueryType>(
|
||||||
|
@ -1,14 +1,44 @@
|
|||||||
import graphql from 'babel-plugin-relay/macro'
|
import graphql from 'babel-plugin-relay/macro'
|
||||||
import { TimePeriod, TokenData } from 'hooks/useExplorePageQuery'
|
|
||||||
import { useLazyLoadQuery } from 'react-relay'
|
import { useLazyLoadQuery } from 'react-relay'
|
||||||
|
|
||||||
import type { TopTokenQuery as TopTokenQueryType } from './__generated__/TopTokenQuery.graphql'
|
import type { Chain, Currency, TopTokenQuery as TopTokenQueryType } from './__generated__/TopTokenQuery.graphql'
|
||||||
|
|
||||||
|
export enum TimePeriod {
|
||||||
|
HOUR,
|
||||||
|
DAY,
|
||||||
|
WEEK,
|
||||||
|
MONTH,
|
||||||
|
YEAR,
|
||||||
|
ALL,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAmount {
|
||||||
|
currency: Currency | null
|
||||||
|
value: number | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TokenData = {
|
||||||
|
name: string | null
|
||||||
|
address: string
|
||||||
|
chain: Chain | null
|
||||||
|
symbol: string | null
|
||||||
|
price: IAmount | null | undefined
|
||||||
|
marketCap: IAmount | null | undefined
|
||||||
|
volume: Record<TimePeriod, IAmount | null | undefined>
|
||||||
|
percentChange: Record<TimePeriod, IAmount | null | undefined>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UseTopTokensResult {
|
||||||
|
data: TokenData[] | undefined
|
||||||
|
error: string | null
|
||||||
|
loading: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export function useTopTokenQuery(page: number) {
|
export function useTopTokenQuery(page: number) {
|
||||||
const topTokenData = useLazyLoadQuery<TopTokenQueryType>(
|
const topTokenData = useLazyLoadQuery<TopTokenQueryType>(
|
||||||
graphql`
|
graphql`
|
||||||
query TopTokenQuery($page: Int!) {
|
query TopTokenQuery($page: Int!) {
|
||||||
topTokenProjects(orderBy: MARKET_CAP, pageSize: 50, currency: USD, page: $page) {
|
topTokenProjects(orderBy: MARKET_CAP, pageSize: 100, currency: USD, page: $page) {
|
||||||
name
|
name
|
||||||
tokens {
|
tokens {
|
||||||
chain
|
chain
|
||||||
@ -85,12 +115,11 @@ export function useTopTokenQuery(page: number) {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const topTokens: Record<string, TokenData> =
|
const topTokens: TokenData[] | undefined = topTokenData.topTokenProjects?.map((token) =>
|
||||||
topTokenData.topTokenProjects?.reduce((acc, token) => {
|
token?.tokens?.[0].address
|
||||||
const tokenAddress = token?.tokens?.[0].address
|
? {
|
||||||
if (tokenAddress) {
|
|
||||||
acc[tokenAddress] = {
|
|
||||||
name: token?.name,
|
name: token?.name,
|
||||||
|
address: token?.tokens?.[0].address,
|
||||||
chain: token?.tokens?.[0].chain,
|
chain: token?.tokens?.[0].chain,
|
||||||
symbol: token?.tokens?.[0].symbol,
|
symbol: token?.tokens?.[0].symbol,
|
||||||
price: token?.markets?.[0]?.price,
|
price: token?.markets?.[0]?.price,
|
||||||
@ -112,8 +141,7 @@ export function useTopTokenQuery(page: number) {
|
|||||||
[TimePeriod.ALL]: token?.markets?.[0]?.pricePercentChangeAll,
|
[TimePeriod.ALL]: token?.markets?.[0]?.pricePercentChangeAll,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
: ({} as TokenData)
|
||||||
return acc
|
)
|
||||||
}, {} as Record<string, TokenData>) ?? {}
|
|
||||||
return topTokens
|
return topTokens
|
||||||
}
|
}
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
import { Chain, Currency } from 'graphql/data/__generated__/TopTokenQuery.graphql'
|
|
||||||
import { useTopTokenQuery } from 'graphql/data/TopTokenQuery'
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
|
|
||||||
export enum TimePeriod {
|
|
||||||
HOUR,
|
|
||||||
DAY,
|
|
||||||
WEEK,
|
|
||||||
MONTH,
|
|
||||||
YEAR,
|
|
||||||
ALL,
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IAmount {
|
|
||||||
currency: Currency | null
|
|
||||||
value: number | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TokenData = {
|
|
||||||
name: string | null | undefined
|
|
||||||
chain: Chain | undefined
|
|
||||||
symbol: string | null | undefined
|
|
||||||
price: IAmount | null | undefined
|
|
||||||
marketCap: IAmount | null | undefined
|
|
||||||
volume: Record<TimePeriod, IAmount | null | undefined>
|
|
||||||
percentChange: Record<TimePeriod, IAmount | null | undefined>
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UseTopTokensResult {
|
|
||||||
data: Record<string, TokenData> | null
|
|
||||||
error: string | null
|
|
||||||
loading: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const useExplorePageQuery = (): UseTopTokensResult => {
|
|
||||||
const [data, setData] = useState<Record<string, TokenData> | null>(null)
|
|
||||||
const [error, setError] = useState<string | null>(null)
|
|
||||||
const [loading, setLoading] = useState(false)
|
|
||||||
|
|
||||||
const FetchTopTokens = async (): Promise<Record<string, TokenData> | void> => {
|
|
||||||
try {
|
|
||||||
const topTokens = useTopTokenQuery(1)
|
|
||||||
return topTokens
|
|
||||||
} catch (e) {
|
|
||||||
setError('Error fetching top tokens')
|
|
||||||
} finally {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setError(null)
|
|
||||||
setLoading(true)
|
|
||||||
FetchTopTokens()
|
|
||||||
.then((data) => {
|
|
||||||
if (data) setData(data)
|
|
||||||
})
|
|
||||||
.catch((e) => setError(e))
|
|
||||||
.finally(() => setLoading(false))
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return { data, error, loading }
|
|
||||||
}
|
|
||||||
|
|
||||||
export default useExplorePageQuery
|
|
Loading…
Reference in New Issue
Block a user