diff --git a/explorer/src/components/SupplyCard.tsx b/explorer/src/components/SupplyCard.tsx index 9afb561003e6f4..8d86a1bef6cfaa 100644 --- a/explorer/src/components/SupplyCard.tsx +++ b/explorer/src/components/SupplyCard.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { useSupply, useFetchSupply } from "providers/supply"; +import { useSupply, useFetchSupply, Status } from "providers/supply"; import LoadingCard from "./common/LoadingCard"; import ErrorCard from "./common/ErrorCard"; import { lamportsToSolString } from "utils"; @@ -9,11 +9,18 @@ export default function SupplyCard() { const supply = useSupply(); const fetchSupply = useFetchSupply(); - if (typeof supply === "boolean") { - if (supply) return ; + // Fetch supply on load + React.useEffect(() => { + fetchSupply(); + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + if (supply === Status.Disconnected) { return ; } + if (supply === Status.Idle || supply === Status.Connecting) + return ; + if (typeof supply === "string") { return ; } diff --git a/explorer/src/components/TopAccountsCard.tsx b/explorer/src/components/TopAccountsCard.tsx index 437a8c349390ae..f83789b2367587 100644 --- a/explorer/src/components/TopAccountsCard.tsx +++ b/explorer/src/components/TopAccountsCard.tsx @@ -2,7 +2,7 @@ import React from "react"; import { Link } from "react-router-dom"; import { AccountBalancePair } from "@solana/web3.js"; import Copyable from "./Copyable"; -import { useRichList, useFetchRichList } from "providers/richList"; +import { useRichList, useFetchRichList, Status } from "providers/richList"; import LoadingCard from "./common/LoadingCard"; import ErrorCard from "./common/ErrorCard"; import { lamportsToSolString } from "utils"; @@ -11,11 +11,18 @@ export default function TopAccountsCard() { const richList = useRichList(); const fetchRichList = useFetchRichList(); - if (typeof richList === "boolean") { - if (richList) return ; + // Fetch on load + React.useEffect(() => { + fetchRichList(); + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + if (richList === Status.Disconnected) { return ; } + if (richList === Status.Idle || richList === Status.Connecting) + return ; + if (typeof richList === "string") { return ; } diff --git a/explorer/src/providers/richList.tsx b/explorer/src/providers/richList.tsx index 5ec5e6db079987..23e0d6974e924f 100644 --- a/explorer/src/providers/richList.tsx +++ b/explorer/src/providers/richList.tsx @@ -3,13 +3,19 @@ import React from "react"; import { AccountBalancePair, Connection } from "@solana/web3.js"; import { useCluster, ClusterStatus } from "./cluster"; +export enum Status { + Idle, + Disconnected, + Connecting +} + type RichList = { accounts: AccountBalancePair[]; totalSupply: number; circulatingSupply: number; }; -type State = RichList | boolean | string; +type State = RichList | Status | string; type Dispatch = React.Dispatch>; const StateContext = React.createContext(undefined); @@ -17,13 +23,16 @@ const DispatchContext = React.createContext(undefined); type Props = { children: React.ReactNode }; export function RichListProvider({ children }: Props) { - const [state, setState] = React.useState(false); - const { status, url } = useCluster(); + const [state, setState] = React.useState(Status.Idle); + const { status: clusterStatus, url } = useCluster(); React.useEffect(() => { - if (status === ClusterStatus.Connecting) setState(false); - if (status === ClusterStatus.Connected) fetch(setState, url); - }, [status, url]); + if (state !== Status.Idle) { + if (clusterStatus === ClusterStatus.Connecting) + setState(Status.Disconnected); + if (clusterStatus === ClusterStatus.Connected) fetch(setState, url); + } + }, [clusterStatus, url]); // eslint-disable-line react-hooks/exhaustive-deps return ( @@ -35,7 +44,8 @@ export function RichListProvider({ children }: Props) { } async function fetch(dispatch: Dispatch, url: string) { - dispatch(true); + dispatch(Status.Connecting); + try { const connection = new Connection(url, "max"); const supply = (await connection.getSupply()).value; @@ -43,9 +53,9 @@ async function fetch(dispatch: Dispatch, url: string) { await connection.getLargestAccounts({ filter: "circulating" }) ).value; - // Update state if selected cluster hasn't changed + // Update state if still connecting dispatch(state => { - if (!state) return state; + if (state !== Status.Connecting) return state; return { accounts, totalSupply: supply.total, diff --git a/explorer/src/providers/supply.tsx b/explorer/src/providers/supply.tsx index ad966e8aa8d4b2..6e2da17abc8151 100644 --- a/explorer/src/providers/supply.tsx +++ b/explorer/src/providers/supply.tsx @@ -3,7 +3,13 @@ import React from "react"; import { Supply, Connection } from "@solana/web3.js"; import { useCluster, ClusterStatus } from "./cluster"; -type State = Supply | boolean | string; +export enum Status { + Idle, + Disconnected, + Connecting +} + +type State = Supply | Status | string; type Dispatch = React.Dispatch>; const StateContext = React.createContext(undefined); @@ -11,13 +17,16 @@ const DispatchContext = React.createContext(undefined); type Props = { children: React.ReactNode }; export function SupplyProvider({ children }: Props) { - const [state, setState] = React.useState(false); - const { status, url } = useCluster(); + const [state, setState] = React.useState(Status.Idle); + const { status: clusterStatus, url } = useCluster(); React.useEffect(() => { - if (status === ClusterStatus.Connecting) setState(false); - if (status === ClusterStatus.Connected) fetch(setState, url); - }, [status, url]); + if (state !== Status.Idle) { + if (clusterStatus === ClusterStatus.Connecting) + setState(Status.Disconnected); + if (clusterStatus === ClusterStatus.Connected) fetch(setState, url); + } + }, [clusterStatus, url]); // eslint-disable-line react-hooks/exhaustive-deps return ( @@ -29,14 +38,15 @@ export function SupplyProvider({ children }: Props) { } async function fetch(dispatch: Dispatch, url: string) { - dispatch(true); + dispatch(Status.Connecting); + try { const connection = new Connection(url, "max"); const supply = (await connection.getSupply()).value; - // Update state if selected cluster hasn't changed + // Update state if still connecting dispatch(state => { - if (!state) return state; + if (state !== Status.Connecting) return state; return supply; }); } catch (err) {