From d8107d6686dcaca29e926ff5934acd964de6d904 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 23 Sep 2020 19:37:46 +0200 Subject: [PATCH] fix hooks dependencies, prevent some rerenders --- src/hooks/useCompute/useCompute.ts | 3 +- src/hooks/useMetadata/useMetadata.ts | 34 ++++--- src/hooks/usePublish/usePublish.ts | 4 +- src/providers/OceanProvider/OceanProvider.tsx | 96 ++++++++++--------- 4 files changed, 73 insertions(+), 64 deletions(-) diff --git a/src/hooks/useCompute/useCompute.ts b/src/hooks/useCompute/useCompute.ts index 6fd658c..8fef8b8 100644 --- a/src/hooks/useCompute/useCompute.ts +++ b/src/hooks/useCompute/useCompute.ts @@ -1,8 +1,7 @@ import { useState } from 'react' import { useOcean } from '../../providers' import { ComputeValue } from './ComputeOptions' -import { feedback } from './../../utils' -import { DID, Logger } from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import { MetadataAlgorithm } from '@oceanprotocol/lib/dist/node/ddo/interfaces/MetadataAlgorithm' import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/ComputeJob' import { checkAndBuyDT } from '../../utils/dtUtils' diff --git a/src/hooks/useMetadata/useMetadata.ts b/src/hooks/useMetadata/useMetadata.ts index fe9e7fb..5d20cf3 100644 --- a/src/hooks/useMetadata/useMetadata.ts +++ b/src/hooks/useMetadata/useMetadata.ts @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import { useState, useEffect, useCallback } from 'react' import { DID, DDO, Metadata, Logger } from '@oceanprotocol/lib' import { useOcean } from '../../providers' import ProviderStatus from '../../providers/OceanProvider/ProviderStatus' @@ -25,23 +25,29 @@ function useMetadata(asset?: DID | string | DDO): UseMetadata { const [isLoaded, setIsLoaded] = useState(false) const [price, setPrice] = useState() - async function getDDO(did: DID | string): Promise { - if (status !== ProviderStatus.CONNECTED) return null + const getDDO = useCallback( + async (did: DID | string): Promise => { + if (status !== ProviderStatus.CONNECTED) return null - const ddo = await ocean.metadatastore.retrieveDDO(did) - return ddo - } + const ddo = await ocean.metadatastore.retrieveDDO(did) + return ddo + }, + [ocean?.metadatastore, status] + ) - async function getPrice(dataTokenAddress?: string): Promise { - if (!dataTokenAddress) dataTokenAddress = internalDdo.dataToken - return await getBestDataTokenPrice(ocean, dataTokenAddress, accountId) - } + const getPrice = useCallback( + async (dataTokenAddress?: string): Promise => { + if (!dataTokenAddress) dataTokenAddress = internalDdo.dataToken + return await getBestDataTokenPrice(ocean, dataTokenAddress, accountId) + }, + [ocean, accountId, internalDdo?.dataToken] + ) - async function getMetadata(): Promise { + const getMetadata = useCallback(async (): Promise => { if (!internalDdo) return null const metadata = internalDdo.findServiceByType('metadata') return metadata.attributes - } + }, [internalDdo]) useEffect(() => { async function init(): Promise { @@ -60,7 +66,7 @@ function useMetadata(asset?: DID | string | DDO): UseMetadata { } } init() - }, [ocean, status]) + }, [ocean, status, asset, getDDO]) useEffect(() => { if (!accountId) return @@ -83,7 +89,7 @@ function useMetadata(asset?: DID | string | DDO): UseMetadata { setPrice(price) }, 10000) return () => clearInterval(interval) - }, [accountId, internalDdo]) + }, [accountId, internalDdo, getMetadata, getPrice]) return { ddo: internalDdo, diff --git a/src/hooks/usePublish/usePublish.ts b/src/hooks/usePublish/usePublish.ts index 638832c..8095d30 100644 --- a/src/hooks/usePublish/usePublish.ts +++ b/src/hooks/usePublish/usePublish.ts @@ -49,7 +49,7 @@ function usePublish(): UsePublish { ): Promise { switch (priceOptions.type) { case 'dynamic': { - const pool = await ocean.pool.createDTPool( + await ocean.pool.createDTPool( accountId, dataTokenAddress, priceOptions.tokensToMint.toString(), @@ -64,7 +64,7 @@ function usePublish(): UsePublish { return null } - const fixedPriceExchange = await ocean.fixedRateExchange.create( + await ocean.fixedRateExchange.create( dataTokenAddress, priceOptions.price.toString(), accountId diff --git a/src/providers/OceanProvider/OceanProvider.tsx b/src/providers/OceanProvider/OceanProvider.tsx index 4d4c7b7..d64ed9d 100644 --- a/src/providers/OceanProvider/OceanProvider.tsx +++ b/src/providers/OceanProvider/OceanProvider.tsx @@ -3,7 +3,9 @@ import React, { useState, useEffect, createContext, - ReactElement + ReactElement, + useCallback, + ReactNode } from 'react' import Web3 from 'web3' import ProviderStatus from './ProviderStatus' @@ -42,7 +44,7 @@ function OceanProvider({ }: { initialConfig: Config web3ModalOpts?: Partial - children: any + children: ReactNode }): ReactElement { const [web3, setWeb3] = useState() const [web3Provider, setWeb3Provider] = useState() @@ -60,71 +62,74 @@ function OceanProvider({ ProviderStatus.NOT_AVAILABLE ) - async function init() { + const init = useCallback(async () => { Logger.log('Ocean Provider init') window && window.ethereum && (window.ethereum.autoRefreshOnNetworkChange = false) Logger.log('Web3Modal init.') - if (web3ModalOpts === undefined) { - web3ModalOpts = await getDefaultProviders() - } - const web3ModalInstance = new Web3Modal(web3ModalOpts) + + const web3ModalInstance = new Web3Modal( + web3ModalOpts || (await getDefaultProviders()) + ) setWeb3Modal(web3ModalInstance) Logger.log('Web3Modal instance created.', web3ModalInstance) - } + }, [web3ModalOpts]) - async function connect(newConfig?: Config) { - try { - Logger.log('Connecting ...', newConfig) + const connect = useCallback( + async (newConfig?: Config) => { + try { + Logger.log('Connecting ...', newConfig) - newConfig && setConfig(newConfig) + newConfig && setConfig(newConfig) - const provider = await web3Modal?.connect() - setWeb3Provider(provider) + const provider = await web3Modal?.connect() + setWeb3Provider(provider) - const web3 = new Web3(provider) - setWeb3(web3) - Logger.log('Web3 created.', web3) + const web3 = new Web3(provider) + setWeb3(web3) + Logger.log('Web3 created.', web3) - const chainId = web3 && (await web3.eth.getChainId()) - setChainId(chainId) - Logger.log('chain id ', chainId) + const chainId = web3 && (await web3.eth.getChainId()) + setChainId(chainId) + Logger.log('chain id ', chainId) - config.web3Provider = web3 - const ocean = await Ocean.getInstance(config) - setOcean(ocean) - Logger.log('Ocean instance created.', ocean) + config.web3Provider = web3 + const ocean = await Ocean.getInstance(config) + setOcean(ocean) + Logger.log('Ocean instance created.', ocean) - setStatus(ProviderStatus.CONNECTED) + setStatus(ProviderStatus.CONNECTED) - const account = (await ocean.accounts.list())[0] - setAccount(account) - Logger.log('Account ', account) + const account = (await ocean.accounts.list())[0] + setAccount(account) + Logger.log('Account ', account) - const accountId = await getAccountId(web3) - setAccountId(accountId) - Logger.log('account id', accountId) + const accountId = await getAccountId(web3) + setAccountId(accountId) + Logger.log('account id', accountId) - const balance = await getBalance(account) - setBalance(balance) - Logger.log('balance', JSON.stringify(balance)) - } catch (error) { - Logger.error(error) - } - } + const balance = await getBalance(account) + setBalance(balance) + Logger.log('balance', JSON.stringify(balance)) + } catch (error) { + Logger.error(error) + } + }, + [config, web3Modal] + ) // On mount setup Web3Modal instance useEffect(() => { init() - }, []) + }, [init]) // Connect automatically to cached provider if present useEffect(() => { if (!web3Modal) return web3Modal.cachedProvider && connect() - }, [web3Modal]) + }, [web3Modal, connect]) async function refreshBalance() { const balance = account && (await getBalance(account)) @@ -135,14 +140,13 @@ function OceanProvider({ web3Modal?.clearCachedProvider() } - const handleAccountsChanged = async (accounts: string[]) => { - Logger.debug("Handling 'accountsChanged' event with payload", accounts) - connect() - } - // TODO: #68 Refetch balance periodically, or figure out some event to subscribe to useEffect(() => { + const handleAccountsChanged = async (accounts: string[]) => { + Logger.debug("Handling 'accountsChanged' event with payload", accounts) + connect() + } // web3Modal && web3Modal.on('connect', handleConnect) if (web3Provider !== undefined && web3Provider !== null) { @@ -154,7 +158,7 @@ function OceanProvider({ // web3Provider.removeListener('chainChanged', handleNetworkChanged) } } - }, [web3Modal, web3Provider]) + }, [web3Modal, web3Provider, connect]) return (