Commit a5b152da authored by Zach Pomerantz's avatar Zach Pomerantz Committed by GitHub

fix: memoize hooks from /swap (#2949)

* fix: memoize hooks from /swap

* chore: rm console
parent 38cf4f46
import { useMemo } from 'react'
import { isAddress } from '../utils' import { isAddress } from '../utils'
import useENSAddress from './useENSAddress' import useENSAddress from './useENSAddress'
import useENSName from './useENSName' import useENSName from './useENSName'
...@@ -15,9 +17,12 @@ export default function useENS(nameOrAddress?: string | null): { ...@@ -15,9 +17,12 @@ export default function useENS(nameOrAddress?: string | null): {
const reverseLookup = useENSName(validated ? validated : undefined) const reverseLookup = useENSName(validated ? validated : undefined)
const lookup = useENSAddress(nameOrAddress) const lookup = useENSAddress(nameOrAddress)
return { return useMemo(
() => ({
loading: reverseLookup.loading || lookup.loading, loading: reverseLookup.loading || lookup.loading,
address: validated ? validated : lookup.address, address: validated ? validated : lookup.address,
name: reverseLookup.ENSName ? reverseLookup.ENSName : !validated && lookup.address ? nameOrAddress || null : null, name: reverseLookup.ENSName ? reverseLookup.ENSName : !validated && lookup.address ? nameOrAddress || null : null,
} }),
[lookup.address, lookup.loading, nameOrAddress, reverseLookup.ENSName, reverseLookup.loading, validated]
)
} }
...@@ -25,8 +25,11 @@ export default function useENSAddress(ensName?: string | null): { loading: boole ...@@ -25,8 +25,11 @@ export default function useENSAddress(ensName?: string | null): { loading: boole
const addr = useSingleCallResult(resolverContract, 'addr', ensNodeArgument) const addr = useSingleCallResult(resolverContract, 'addr', ensNodeArgument)
const changed = debouncedName !== ensName const changed = debouncedName !== ensName
return { return useMemo(
() => ({
address: changed ? null : addr.result?.[0] ?? null, address: changed ? null : addr.result?.[0] ?? null,
loading: changed || resolverAddress.loading || addr.loading, loading: changed || resolverAddress.loading || addr.loading,
} }),
[addr.loading, addr.result, changed, resolverAddress.loading]
)
} }
...@@ -36,10 +36,13 @@ export default function useENSAvatar( ...@@ -36,10 +36,13 @@ export default function useENSAvatar(
const http = avatar && uriToHttp(avatar)[0] const http = avatar && uriToHttp(avatar)[0]
const changed = debouncedAddress !== address const changed = debouncedAddress !== address
return { return useMemo(
() => ({
avatar: changed ? null : http ?? null, avatar: changed ? null : http ?? null,
loading: changed || addressAvatar.loading || nameAvatar.loading || nftAvatar.loading, loading: changed || addressAvatar.loading || nameAvatar.loading || nftAvatar.loading,
} }),
[addressAvatar.loading, changed, http, nameAvatar.loading, nftAvatar.loading]
)
} }
function useAvatarFromNode(node?: string): { avatar?: string; loading: boolean } { function useAvatarFromNode(node?: string): { avatar?: string; loading: boolean } {
...@@ -54,10 +57,13 @@ function useAvatarFromNode(node?: string): { avatar?: string; loading: boolean } ...@@ -54,10 +57,13 @@ function useAvatarFromNode(node?: string): { avatar?: string; loading: boolean }
) )
const avatar = useSingleCallResult(resolverContract, 'text', textArgument) const avatar = useSingleCallResult(resolverContract, 'text', textArgument)
return { return useMemo(
() => ({
avatar: avatar.result?.[0], avatar: avatar.result?.[0],
loading: resolverAddress.loading || avatar.loading, loading: resolverAddress.loading || avatar.loading,
} }),
[avatar.loading, avatar.result, resolverAddress.loading]
)
} }
function useAvatarFromNFT(nftUri = '', enforceOwnership: boolean): { avatar?: string; loading: boolean } { function useAvatarFromNFT(nftUri = '', enforceOwnership: boolean): { avatar?: string; loading: boolean } {
...@@ -92,7 +98,10 @@ function useAvatarFromNFT(nftUri = '', enforceOwnership: boolean): { avatar?: st ...@@ -92,7 +98,10 @@ function useAvatarFromNFT(nftUri = '', enforceOwnership: boolean): { avatar?: st
} }
}, [http]) }, [http])
return { avatar, loading: erc721.loading || erc1155.loading || loading } return useMemo(
() => ({ avatar, loading: erc721.loading || erc1155.loading || loading }),
[avatar, erc1155.loading, erc721.loading, loading]
)
} }
function useERC721Uri( function useERC721Uri(
...@@ -105,10 +114,13 @@ function useERC721Uri( ...@@ -105,10 +114,13 @@ function useERC721Uri(
const contract = useERC721Contract(contractAddress) const contract = useERC721Contract(contractAddress)
const owner = useSingleCallResult(contract, 'ownerOf', idArgument) const owner = useSingleCallResult(contract, 'ownerOf', idArgument)
const uri = useSingleCallResult(contract, 'tokenURI', idArgument) const uri = useSingleCallResult(contract, 'tokenURI', idArgument)
return { return useMemo(
() => ({
uri: !enforceOwnership || account === owner.result?.[0] ? uri.result?.[0] : undefined, uri: !enforceOwnership || account === owner.result?.[0] ? uri.result?.[0] : undefined,
loading: owner.loading || uri.loading, loading: owner.loading || uri.loading,
} }),
[account, enforceOwnership, owner.loading, owner.result, uri.loading, uri.result]
)
} }
function useERC1155Uri( function useERC1155Uri(
...@@ -122,8 +134,11 @@ function useERC1155Uri( ...@@ -122,8 +134,11 @@ function useERC1155Uri(
const contract = useERC1155Contract(contractAddress) const contract = useERC1155Contract(contractAddress)
const balance = useSingleCallResult(contract, 'balanceOf', accountArgument) const balance = useSingleCallResult(contract, 'balanceOf', accountArgument)
const uri = useSingleCallResult(contract, 'uri', idArgument) const uri = useSingleCallResult(contract, 'uri', idArgument)
return { return useMemo(
() => ({
uri: !enforceOwnership || balance.result?.[0] > 0 ? uri.result?.[0] : undefined, uri: !enforceOwnership || balance.result?.[0] > 0 ? uri.result?.[0] : undefined,
loading: balance.loading || uri.loading, loading: balance.loading || uri.loading,
} }),
[balance.loading, balance.result, enforceOwnership, uri.loading, uri.result]
)
} }
...@@ -19,8 +19,11 @@ export default function useENSContentHash(ensName?: string | null): { loading: b ...@@ -19,8 +19,11 @@ export default function useENSContentHash(ensName?: string | null): { loading: b
) )
const contenthash = useSingleCallResult(resolverContract, 'contenthash', ensNodeArgument) const contenthash = useSingleCallResult(resolverContract, 'contenthash', ensNodeArgument)
return { return useMemo(
() => ({
contenthash: contenthash.result?.[0] ?? null, contenthash: contenthash.result?.[0] ?? null,
loading: resolverAddressResult.loading || contenthash.loading, loading: resolverAddressResult.loading || contenthash.loading,
} }),
[contenthash.loading, contenthash.result, resolverAddressResult.loading]
)
} }
...@@ -27,8 +27,11 @@ export default function useENSName(address?: string): { ENSName: string | null; ...@@ -27,8 +27,11 @@ export default function useENSName(address?: string): { ENSName: string | null;
const name = useSingleCallResult(resolverContract, 'name', ensNodeArgument) const name = useSingleCallResult(resolverContract, 'name', ensNodeArgument)
const changed = debouncedAddress !== address const changed = debouncedAddress !== address
return { return useMemo(
() => ({
ENSName: changed ? null : name.result?.[0] ?? null, ENSName: changed ? null : name.result?.[0] ?? null,
loading: changed || resolverAddress.loading || name.loading, loading: changed || resolverAddress.loading || name.loading,
} }),
[changed, name.loading, name.result, resolverAddress.loading]
)
} }
...@@ -96,11 +96,14 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -96,11 +96,14 @@ export default function Swap({ history }: RouteComponentProps) {
// dismiss warning if all imported tokens are in active lists // dismiss warning if all imported tokens are in active lists
const defaultTokens = useAllTokens() const defaultTokens = useAllTokens()
const importTokensNotInDefault = const importTokensNotInDefault = useMemo(
() =>
urlLoadedTokens && urlLoadedTokens &&
urlLoadedTokens.filter((token: Token) => { urlLoadedTokens.filter((token: Token) => {
return !Boolean(token.address in defaultTokens) return !Boolean(token.address in defaultTokens)
}) }),
[defaultTokens, urlLoadedTokens]
)
const theme = useContext(ThemeContext) const theme = useContext(ThemeContext)
...@@ -198,12 +201,15 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -198,12 +201,15 @@ export default function Swap({ history }: RouteComponentProps) {
txHash: undefined, txHash: undefined,
}) })
const formattedAmounts = { const formattedAmounts = useMemo(
() => ({
[independentField]: typedValue, [independentField]: typedValue,
[dependentField]: showWrap [dependentField]: showWrap
? parsedAmounts[independentField]?.toExact() ?? '' ? parsedAmounts[independentField]?.toExact() ?? ''
: parsedAmounts[dependentField]?.toSignificant(6) ?? '', : parsedAmounts[dependentField]?.toSignificant(6) ?? '',
} }),
[dependentField, independentField, parsedAmounts, showWrap, typedValue]
)
const userHasSpecifiedInputOutput = Boolean( const userHasSpecifiedInputOutput = Boolean(
currencies[Field.INPUT] && currencies[Field.OUTPUT] && parsedAmounts[independentField]?.greaterThan(JSBI.BigInt(0)) currencies[Field.INPUT] && currencies[Field.OUTPUT] && parsedAmounts[independentField]?.greaterThan(JSBI.BigInt(0))
...@@ -248,7 +254,10 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -248,7 +254,10 @@ export default function Swap({ history }: RouteComponentProps) {
} }
}, [approvalState, approvalSubmitted]) }, [approvalState, approvalSubmitted])
const maxInputAmount: CurrencyAmount<Currency> | undefined = maxAmountSpend(currencyBalances[Field.INPUT]) const maxInputAmount: CurrencyAmount<Currency> | undefined = useMemo(
() => maxAmountSpend(currencyBalances[Field.INPUT]),
[currencyBalances]
)
const showMaxButton = Boolean(maxInputAmount?.greaterThan(0) && !parsedAmounts[Field.INPUT]?.equalTo(maxInputAmount)) const showMaxButton = Boolean(maxInputAmount?.greaterThan(0) && !parsedAmounts[Field.INPUT]?.equalTo(maxInputAmount))
// the callback to execute the swap // the callback to execute the swap
......
...@@ -91,10 +91,10 @@ export function useDerivedMintInfo( ...@@ -91,10 +91,10 @@ export function useDerivedMintInfo(
) )
// balances // balances
const balances = useCurrencyBalances(account ?? undefined, [ const balances = useCurrencyBalances(
currencies[Field.CURRENCY_A], account ?? undefined,
currencies[Field.CURRENCY_B], useMemo(() => [currencies[Field.CURRENCY_A], currencies[Field.CURRENCY_B]], [currencies])
]) )
const currencyBalances: { [field in Field]?: CurrencyAmount<Currency> } = { const currencyBalances: { [field in Field]?: CurrencyAmount<Currency> } = {
[Field.CURRENCY_A]: balances[0], [Field.CURRENCY_A]: balances[0],
[Field.CURRENCY_B]: balances[1], [Field.CURRENCY_B]: balances[1],
......
...@@ -150,10 +150,10 @@ export function useV3DerivedMintInfo( ...@@ -150,10 +150,10 @@ export function useV3DerivedMintInfo(
) )
// balances // balances
const balances = useCurrencyBalances(account ?? undefined, [ const balances = useCurrencyBalances(
currencies[Field.CURRENCY_A], account ?? undefined,
currencies[Field.CURRENCY_B], useMemo(() => [currencies[Field.CURRENCY_A], currencies[Field.CURRENCY_B]], [currencies])
]) )
const currencyBalances: { [field in Field]?: CurrencyAmount<Currency> } = { const currencyBalances: { [field in Field]?: CurrencyAmount<Currency> } = {
[Field.CURRENCY_A]: balances[0], [Field.CURRENCY_A]: balances[0],
[Field.CURRENCY_B]: balances[1], [Field.CURRENCY_B]: balances[1],
......
...@@ -145,10 +145,10 @@ export function useDerivedSwapInfo(toggledVersion: Version | undefined): { ...@@ -145,10 +145,10 @@ export function useDerivedSwapInfo(toggledVersion: Version | undefined): {
const recipientLookup = useENS(recipient ?? undefined) const recipientLookup = useENS(recipient ?? undefined)
const to: string | null = (recipient === null ? account : recipientLookup.address) ?? null const to: string | null = (recipient === null ? account : recipientLookup.address) ?? null
const relevantTokenBalances = useCurrencyBalances(account ?? undefined, [ const relevantTokenBalances = useCurrencyBalances(
inputCurrency ?? undefined, account ?? undefined,
outputCurrency ?? undefined, useMemo(() => [inputCurrency ?? undefined, outputCurrency ?? undefined], [inputCurrency, outputCurrency])
]) )
const isExactIn: boolean = independentField === Field.INPUT const isExactIn: boolean = independentField === Field.INPUT
const parsedAmount = useMemo( const parsedAmount = useMemo(
......
...@@ -51,6 +51,9 @@ export function useETHBalances(uncheckedAddresses?: (string | undefined)[]): { ...@@ -51,6 +51,9 @@ export function useETHBalances(uncheckedAddresses?: (string | undefined)[]): {
) )
} }
const ERC20Interface = new Interface(ERC20ABI) as Erc20Interface
const tokenBalancesGasRequirement = { gasRequired: 125_000 }
/** /**
* Returns a map of token addresses to their eventually consistent token balances for a single account. * Returns a map of token addresses to their eventually consistent token balances for a single account.
*/ */
...@@ -62,18 +65,20 @@ export function useTokenBalancesWithLoadingIndicator( ...@@ -62,18 +65,20 @@ export function useTokenBalancesWithLoadingIndicator(
() => tokens?.filter((t?: Token): t is Token => isAddress(t?.address) !== false) ?? [], () => tokens?.filter((t?: Token): t is Token => isAddress(t?.address) !== false) ?? [],
[tokens] [tokens]
) )
const validatedTokenAddresses = useMemo(() => validatedTokens.map((vt) => vt.address), [validatedTokens]) const validatedTokenAddresses = useMemo(() => validatedTokens.map((vt) => vt.address), [validatedTokens])
const ERC20Interface = new Interface(ERC20ABI) as Erc20Interface
const balances = useMultipleContractSingleData(validatedTokenAddresses, ERC20Interface, 'balanceOf', [address], { const balances = useMultipleContractSingleData(
gasRequired: 125_000, validatedTokenAddresses,
}) ERC20Interface,
'balanceOf',
useMemo(() => [address], [address]),
tokenBalancesGasRequirement
)
const anyLoading: boolean = useMemo(() => balances.some((callState) => callState.loading), [balances]) const anyLoading: boolean = useMemo(() => balances.some((callState) => callState.loading), [balances])
return [ return useMemo(
useMemo( () => [
() =>
address && validatedTokens.length > 0 address && validatedTokens.length > 0
? validatedTokens.reduce<{ [tokenAddress: string]: CurrencyAmount<Token> | undefined }>((memo, token, i) => { ? validatedTokens.reduce<{ [tokenAddress: string]: CurrencyAmount<Token> | undefined }>((memo, token, i) => {
const value = balances?.[i]?.result?.[0] const value = balances?.[i]?.result?.[0]
...@@ -84,10 +89,10 @@ export function useTokenBalancesWithLoadingIndicator( ...@@ -84,10 +89,10 @@ export function useTokenBalancesWithLoadingIndicator(
return memo return memo
}, {}) }, {})
: {}, : {},
[address, validatedTokens, balances]
),
anyLoading, anyLoading,
] ],
[address, validatedTokens, anyLoading, balances]
)
} }
export function useTokenBalances( export function useTokenBalances(
...@@ -130,7 +135,10 @@ export function useCurrencyBalances( ...@@ -130,7 +135,10 @@ export function useCurrencyBalances(
} }
export function useCurrencyBalance(account?: string, currency?: Currency): CurrencyAmount<Currency> | undefined { export function useCurrencyBalance(account?: string, currency?: Currency): CurrencyAmount<Currency> | undefined {
return useCurrencyBalances(account, [currency])[0] return useCurrencyBalances(
account,
useMemo(() => [currency], [currency])
)[0]
} }
// mimics useAllBalances // mimics useAllBalances
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment