From 918d68eb01b918f2994cb26bdc3de912d414560c Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Wed, 1 Dec 2021 10:58:16 +0100 Subject: [PATCH] Fix: avoid loading safe multiple times Lint --- src/components/App/index.tsx | 4 +- src/logic/safe/hooks/useLoadSafe.tsx | 32 +++++----------- .../safe/hooks/useSafeScheduledUpdates.tsx | 37 ++++++++----------- src/logic/safe/store/actions/fetchSafe.ts | 7 ++-- .../components/Apps/components/AppFrame.tsx | 4 +- src/utils/constants.ts | 2 +- 6 files changed, 33 insertions(+), 53 deletions(-) diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 0954534dec..aba293456b 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -62,9 +62,9 @@ const App: React.FC = ({ children }) => { const currentCurrency = useSelector(currentCurrencySelector) const granted = useSelector(grantedSelector) const sidebarItems = useSidebarItems() - const safeLoaded = useLoadSafe(addressFromUrl) const dispatch = useDispatch() - useSafeScheduledUpdates(safeLoaded, addressFromUrl) + useLoadSafe(addressFromUrl) // load initially + useSafeScheduledUpdates(addressFromUrl) // load every X seconds useAddressBookSync() const sendFunds = safeActionsState.sendFunds diff --git a/src/logic/safe/hooks/useLoadSafe.tsx b/src/logic/safe/hooks/useLoadSafe.tsx index 6625a99e7d..6f4ef156f9 100644 --- a/src/logic/safe/hooks/useLoadSafe.tsx +++ b/src/logic/safe/hooks/useLoadSafe.tsx @@ -1,37 +1,25 @@ -import { useEffect, useState } from 'react' +import { useEffect } from 'react' import { useDispatch, useSelector } from 'react-redux' import addViewedSafe from 'src/logic/currentSession/store/actions/addViewedSafe' import fetchLatestMasterContractVersion from 'src/logic/safe/store/actions/fetchLatestMasterContractVersion' import { fetchSafe } from 'src/logic/safe/store/actions/fetchSafe' -import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions' import { Dispatch } from 'src/logic/safe/store/actions/types.d' import { updateAvailableCurrencies } from 'src/logic/currencyValues/store/actions/updateAvailableCurrencies' import { currentChainId } from 'src/logic/config/store/selectors' +import { fetchSafeTokens } from 'src/logic/tokens/store/actions/fetchSafeTokens' -export const useLoadSafe = (safeAddress?: string): boolean => { +export const useLoadSafe = (safeAddress?: string): void => { const dispatch = useDispatch() const chainId = useSelector(currentChainId) - const [isSafeLoaded, setIsSafeLoaded] = useState(false) useEffect(() => { - setIsSafeLoaded(false) - }, [safeAddress]) + if (!safeAddress) return - useEffect(() => { - const fetchData = async () => { - if (safeAddress) { - await dispatch(fetchLatestMasterContractVersion()) - await dispatch(fetchSafe(safeAddress, isSafeLoaded)) - - setIsSafeLoaded(true) - await dispatch(updateAvailableCurrencies()) - await dispatch(fetchTransactions(chainId, safeAddress)) - dispatch(addViewedSafe(safeAddress)) - } - } - fetchData() - }, [chainId, dispatch, safeAddress, isSafeLoaded]) - - return isSafeLoaded + dispatch(fetchLatestMasterContractVersion()) + dispatch(fetchSafe(safeAddress)) + dispatch(fetchSafeTokens(safeAddress)) + dispatch(updateAvailableCurrencies()) + dispatch(addViewedSafe(safeAddress)) + }, [dispatch, safeAddress, chainId]) } diff --git a/src/logic/safe/hooks/useSafeScheduledUpdates.tsx b/src/logic/safe/hooks/useSafeScheduledUpdates.tsx index a00830257d..e9e43901de 100644 --- a/src/logic/safe/hooks/useSafeScheduledUpdates.tsx +++ b/src/logic/safe/hooks/useSafeScheduledUpdates.tsx @@ -1,33 +1,26 @@ -import { useEffect, useRef } from 'react' -import { useDispatch } from 'react-redux' +import { useEffect, useState } from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { currentChainId } from 'src/logic/config/store/selectors' import { fetchSafe } from 'src/logic/safe/store/actions/fetchSafe' import { fetchSafeTokens } from 'src/logic/tokens/store/actions/fetchSafeTokens' -import { TIMEOUT } from 'src/utils/constants' +import { SAFE_POLLING_INTERVAL } from 'src/utils/constants' -export const useSafeScheduledUpdates = (safeLoaded: boolean, safeAddress?: string): void => { +export const useSafeScheduledUpdates = (safeAddress?: string): void => { const dispatch = useDispatch() - const timer = useRef() + const [pollCount, setPollCount] = useState(0) + const chainId = useSelector(currentChainId) useEffect(() => { - // using this variable to prevent setting a timeout when the component is already unmounted or the effect - // has to run again - let mounted = true - const fetchSafeData = (address: string): void => { - dispatch(fetchSafe(address, safeLoaded)) - dispatch(fetchSafeTokens(address)) - - if (mounted) { - timer.current = window.setTimeout(() => fetchSafeData(address), TIMEOUT * 3) + const timer = setTimeout(() => { + if (safeAddress) { + dispatch(fetchSafe(safeAddress)) + dispatch(fetchSafeTokens(safeAddress)) } - } - - if (safeAddress && safeLoaded) { - fetchSafeData(safeAddress) - } + setPollCount((prev) => prev + 1) + }, SAFE_POLLING_INTERVAL) return () => { - mounted = false - clearTimeout(timer.current) + clearTimeout(timer) } - }, [dispatch, safeAddress, safeLoaded]) + }, [dispatch, safeAddress, chainId, pollCount, setPollCount]) } diff --git a/src/logic/safe/store/actions/fetchSafe.ts b/src/logic/safe/store/actions/fetchSafe.ts index 050deb017e..4daad273eb 100644 --- a/src/logic/safe/store/actions/fetchSafe.ts +++ b/src/logic/safe/store/actions/fetchSafe.ts @@ -54,10 +54,9 @@ export const buildSafe = async (safeAddress: string): Promise = * @note It's being used by the app when it loads for the first time and for the Safe's data polling * * @param {string} safeAddress - * @param {boolean} isSafeLoaded */ export const fetchSafe = - (safeAddress: string, isSafeLoaded = false) => + (safeAddress: string) => async (dispatch: Dispatch): Promise> | void> => { let address = '' try { @@ -95,11 +94,11 @@ export const fetchSafe = const shouldUpdateTxHistory = txHistoryTag !== safeInfo.txHistoryTag const shouldUpdateTxQueued = txQueuedTag !== safeInfo.txQueuedTag - if (shouldUpdateCollectibles || !isSafeLoaded) { + if (shouldUpdateCollectibles) { dispatch(fetchCollectibles(safeAddress)) } - if (shouldUpdateTxHistory || shouldUpdateTxQueued || !isSafeLoaded) { + if (shouldUpdateTxHistory || shouldUpdateTxQueued) { dispatch(fetchTransactions(getNetworkId(), safeAddress)) } } diff --git a/src/routes/safe/components/Apps/components/AppFrame.tsx b/src/routes/safe/components/Apps/components/AppFrame.tsx index b23d6422d6..815a361a80 100644 --- a/src/routes/safe/components/Apps/components/AppFrame.tsx +++ b/src/routes/safe/components/Apps/components/AppFrame.tsx @@ -26,7 +26,7 @@ import { import { isSameURL } from 'src/utils/url' import { useAnalytics, SAFE_EVENTS } from 'src/utils/googleAnalytics' import { LoadingContainer } from 'src/components/LoaderContainer/index' -import { TIMEOUT } from 'src/utils/constants' +import { SAFE_POLLING_INTERVAL } from 'src/utils/constants' import { ConfirmTxModal } from './ConfirmTxModal' import { useIframeMessageHandler } from '../hooks/useIframeMessageHandler' import { getAppInfoFromUrl, getEmptySafeApp } from '../utils' @@ -117,7 +117,7 @@ const AppFrame = ({ appUrl }: Props): ReactElement => { if (appIsLoading) { timer.current = window.setTimeout(() => { setIsLoadingSlow(true) - }, TIMEOUT) + }, SAFE_POLLING_INTERVAL) errorTimer.current = window.setTimeout(() => { setAppLoadError(() => { throw Error(APP_LOAD_ERROR) diff --git a/src/utils/constants.ts b/src/utils/constants.ts index fbf8dce34a..f2a7ec0b3b 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -20,7 +20,7 @@ export const SAFE_APPS_RPC_TOKEN = process.env.REACT_APP_SAFE_APPS_RPC_INFURA_TO export const LATEST_SAFE_VERSION = process.env.REACT_APP_LATEST_SAFE_VERSION || '1.3.0' export const APP_VERSION = process.env.REACT_APP_APP_VERSION || 'not-defined' export const COLLECTIBLES_SOURCE = process.env.REACT_APP_COLLECTIBLES_SOURCE || 'Gnosis' -export const TIMEOUT = process.env.NODE_ENV === 'test' ? 1500 : 5000 +export const SAFE_POLLING_INTERVAL = process.env.NODE_ENV === 'test' ? 4500 : 15000 export const ETHERSCAN_API_KEY = process.env.REACT_APP_ETHERSCAN_API_KEY || '' export const ETHGASSTATION_API_KEY = process.env.REACT_APP_ETHGASSTATION_API_KEY export const CONFIG_SERVICE_URL =