Skip to content

Commit

Permalink
fix: memoize hooks from /swap (#2949)
Browse files Browse the repository at this point in the history
* fix: memoize hooks from /swap

* chore: rm console
  • Loading branch information
zzmp authored Dec 9, 2021
1 parent 38cf4f4 commit a5b152d
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 81 deletions.
15 changes: 10 additions & 5 deletions src/hooks/useENS.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useMemo } from 'react'

import { isAddress } from '../utils'
import useENSAddress from './useENSAddress'
import useENSName from './useENSName'
Expand All @@ -15,9 +17,12 @@ export default function useENS(nameOrAddress?: string | null): {
const reverseLookup = useENSName(validated ? validated : undefined)
const lookup = useENSAddress(nameOrAddress)

return {
loading: reverseLookup.loading || lookup.loading,
address: validated ? validated : lookup.address,
name: reverseLookup.ENSName ? reverseLookup.ENSName : !validated && lookup.address ? nameOrAddress || null : null,
}
return useMemo(
() => ({
loading: reverseLookup.loading || lookup.loading,
address: validated ? validated : lookup.address,
name: reverseLookup.ENSName ? reverseLookup.ENSName : !validated && lookup.address ? nameOrAddress || null : null,
}),
[lookup.address, lookup.loading, nameOrAddress, reverseLookup.ENSName, reverseLookup.loading, validated]
)
}
11 changes: 7 additions & 4 deletions src/hooks/useENSAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ export default function useENSAddress(ensName?: string | null): { loading: boole
const addr = useSingleCallResult(resolverContract, 'addr', ensNodeArgument)

const changed = debouncedName !== ensName
return {
address: changed ? null : addr.result?.[0] ?? null,
loading: changed || resolverAddress.loading || addr.loading,
}
return useMemo(
() => ({
address: changed ? null : addr.result?.[0] ?? null,
loading: changed || resolverAddress.loading || addr.loading,
}),
[addr.loading, addr.result, changed, resolverAddress.loading]
)
}
49 changes: 32 additions & 17 deletions src/hooks/useENSAvatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ export default function useENSAvatar(
const http = avatar && uriToHttp(avatar)[0]

const changed = debouncedAddress !== address
return {
avatar: changed ? null : http ?? null,
loading: changed || addressAvatar.loading || nameAvatar.loading || nftAvatar.loading,
}
return useMemo(
() => ({
avatar: changed ? null : http ?? null,
loading: changed || addressAvatar.loading || nameAvatar.loading || nftAvatar.loading,
}),
[addressAvatar.loading, changed, http, nameAvatar.loading, nftAvatar.loading]
)
}

function useAvatarFromNode(node?: string): { avatar?: string; loading: boolean } {
Expand All @@ -54,10 +57,13 @@ function useAvatarFromNode(node?: string): { avatar?: string; loading: boolean }
)
const avatar = useSingleCallResult(resolverContract, 'text', textArgument)

return {
avatar: avatar.result?.[0],
loading: resolverAddress.loading || avatar.loading,
}
return useMemo(
() => ({
avatar: avatar.result?.[0],
loading: resolverAddress.loading || avatar.loading,
}),
[avatar.loading, avatar.result, resolverAddress.loading]
)
}

function useAvatarFromNFT(nftUri = '', enforceOwnership: boolean): { avatar?: string; loading: boolean } {
Expand Down Expand Up @@ -92,7 +98,10 @@ function useAvatarFromNFT(nftUri = '', enforceOwnership: boolean): { avatar?: st
}
}, [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(
Expand All @@ -105,10 +114,13 @@ function useERC721Uri(
const contract = useERC721Contract(contractAddress)
const owner = useSingleCallResult(contract, 'ownerOf', idArgument)
const uri = useSingleCallResult(contract, 'tokenURI', idArgument)
return {
uri: !enforceOwnership || account === owner.result?.[0] ? uri.result?.[0] : undefined,
loading: owner.loading || uri.loading,
}
return useMemo(
() => ({
uri: !enforceOwnership || account === owner.result?.[0] ? uri.result?.[0] : undefined,
loading: owner.loading || uri.loading,
}),
[account, enforceOwnership, owner.loading, owner.result, uri.loading, uri.result]
)
}

function useERC1155Uri(
Expand All @@ -122,8 +134,11 @@ function useERC1155Uri(
const contract = useERC1155Contract(contractAddress)
const balance = useSingleCallResult(contract, 'balanceOf', accountArgument)
const uri = useSingleCallResult(contract, 'uri', idArgument)
return {
uri: !enforceOwnership || balance.result?.[0] > 0 ? uri.result?.[0] : undefined,
loading: balance.loading || uri.loading,
}
return useMemo(
() => ({
uri: !enforceOwnership || balance.result?.[0] > 0 ? uri.result?.[0] : undefined,
loading: balance.loading || uri.loading,
}),
[balance.loading, balance.result, enforceOwnership, uri.loading, uri.result]
)
}
11 changes: 7 additions & 4 deletions src/hooks/useENSContentHash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ export default function useENSContentHash(ensName?: string | null): { loading: b
)
const contenthash = useSingleCallResult(resolverContract, 'contenthash', ensNodeArgument)

return {
contenthash: contenthash.result?.[0] ?? null,
loading: resolverAddressResult.loading || contenthash.loading,
}
return useMemo(
() => ({
contenthash: contenthash.result?.[0] ?? null,
loading: resolverAddressResult.loading || contenthash.loading,
}),
[contenthash.loading, contenthash.result, resolverAddressResult.loading]
)
}
11 changes: 7 additions & 4 deletions src/hooks/useENSName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ export default function useENSName(address?: string): { ENSName: string | null;
const name = useSingleCallResult(resolverContract, 'name', ensNodeArgument)

const changed = debouncedAddress !== address
return {
ENSName: changed ? null : name.result?.[0] ?? null,
loading: changed || resolverAddress.loading || name.loading,
}
return useMemo(
() => ({
ENSName: changed ? null : name.result?.[0] ?? null,
loading: changed || resolverAddress.loading || name.loading,
}),
[changed, name.loading, name.result, resolverAddress.loading]
)
}
33 changes: 21 additions & 12 deletions src/pages/Swap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,14 @@ export default function Swap({ history }: RouteComponentProps) {

// dismiss warning if all imported tokens are in active lists
const defaultTokens = useAllTokens()
const importTokensNotInDefault =
urlLoadedTokens &&
urlLoadedTokens.filter((token: Token) => {
return !Boolean(token.address in defaultTokens)
})
const importTokensNotInDefault = useMemo(
() =>
urlLoadedTokens &&
urlLoadedTokens.filter((token: Token) => {
return !Boolean(token.address in defaultTokens)
}),
[defaultTokens, urlLoadedTokens]
)

const theme = useContext(ThemeContext)

Expand Down Expand Up @@ -198,12 +201,15 @@ export default function Swap({ history }: RouteComponentProps) {
txHash: undefined,
})

const formattedAmounts = {
[independentField]: typedValue,
[dependentField]: showWrap
? parsedAmounts[independentField]?.toExact() ?? ''
: parsedAmounts[dependentField]?.toSignificant(6) ?? '',
}
const formattedAmounts = useMemo(
() => ({
[independentField]: typedValue,
[dependentField]: showWrap
? parsedAmounts[independentField]?.toExact() ?? ''
: parsedAmounts[dependentField]?.toSignificant(6) ?? '',
}),
[dependentField, independentField, parsedAmounts, showWrap, typedValue]
)

const userHasSpecifiedInputOutput = Boolean(
currencies[Field.INPUT] && currencies[Field.OUTPUT] && parsedAmounts[independentField]?.greaterThan(JSBI.BigInt(0))
Expand Down Expand Up @@ -248,7 +254,10 @@ export default function Swap({ history }: RouteComponentProps) {
}
}, [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))

// the callback to execute the swap
Expand Down
8 changes: 4 additions & 4 deletions src/state/mint/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ export function useDerivedMintInfo(
)

// balances
const balances = useCurrencyBalances(account ?? undefined, [
currencies[Field.CURRENCY_A],
currencies[Field.CURRENCY_B],
])
const balances = useCurrencyBalances(
account ?? undefined,
useMemo(() => [currencies[Field.CURRENCY_A], currencies[Field.CURRENCY_B]], [currencies])
)
const currencyBalances: { [field in Field]?: CurrencyAmount<Currency> } = {
[Field.CURRENCY_A]: balances[0],
[Field.CURRENCY_B]: balances[1],
Expand Down
8 changes: 4 additions & 4 deletions src/state/mint/v3/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ export function useV3DerivedMintInfo(
)

// balances
const balances = useCurrencyBalances(account ?? undefined, [
currencies[Field.CURRENCY_A],
currencies[Field.CURRENCY_B],
])
const balances = useCurrencyBalances(
account ?? undefined,
useMemo(() => [currencies[Field.CURRENCY_A], currencies[Field.CURRENCY_B]], [currencies])
)
const currencyBalances: { [field in Field]?: CurrencyAmount<Currency> } = {
[Field.CURRENCY_A]: balances[0],
[Field.CURRENCY_B]: balances[1],
Expand Down
8 changes: 4 additions & 4 deletions src/state/swap/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ export function useDerivedSwapInfo(toggledVersion: Version | undefined): {
const recipientLookup = useENS(recipient ?? undefined)
const to: string | null = (recipient === null ? account : recipientLookup.address) ?? null

const relevantTokenBalances = useCurrencyBalances(account ?? undefined, [
inputCurrency ?? undefined,
outputCurrency ?? undefined,
])
const relevantTokenBalances = useCurrencyBalances(
account ?? undefined,
useMemo(() => [inputCurrency ?? undefined, outputCurrency ?? undefined], [inputCurrency, outputCurrency])
)

const isExactIn: boolean = independentField === Field.INPUT
const parsedAmount = useMemo(
Expand Down
54 changes: 31 additions & 23 deletions src/state/wallet/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -62,32 +65,34 @@ export function useTokenBalancesWithLoadingIndicator(
() => tokens?.filter((t?: Token): t is Token => isAddress(t?.address) !== false) ?? [],
[tokens]
)

const validatedTokenAddresses = useMemo(() => validatedTokens.map((vt) => vt.address), [validatedTokens])
const ERC20Interface = new Interface(ERC20ABI) as Erc20Interface
const balances = useMultipleContractSingleData(validatedTokenAddresses, ERC20Interface, 'balanceOf', [address], {
gasRequired: 125_000,
})

const balances = useMultipleContractSingleData(
validatedTokenAddresses,
ERC20Interface,
'balanceOf',
useMemo(() => [address], [address]),
tokenBalancesGasRequirement
)

const anyLoading: boolean = useMemo(() => balances.some((callState) => callState.loading), [balances])

return [
useMemo(
() =>
address && validatedTokens.length > 0
? validatedTokens.reduce<{ [tokenAddress: string]: CurrencyAmount<Token> | undefined }>((memo, token, i) => {
const value = balances?.[i]?.result?.[0]
const amount = value ? JSBI.BigInt(value.toString()) : undefined
if (amount) {
memo[token.address] = CurrencyAmount.fromRawAmount(token, amount)
}
return memo
}, {})
: {},
[address, validatedTokens, balances]
),
anyLoading,
]
return useMemo(
() => [
address && validatedTokens.length > 0
? validatedTokens.reduce<{ [tokenAddress: string]: CurrencyAmount<Token> | undefined }>((memo, token, i) => {
const value = balances?.[i]?.result?.[0]
const amount = value ? JSBI.BigInt(value.toString()) : undefined
if (amount) {
memo[token.address] = CurrencyAmount.fromRawAmount(token, amount)
}
return memo
}, {})
: {},
anyLoading,
],
[address, validatedTokens, anyLoading, balances]
)
}

export function useTokenBalances(
Expand Down Expand Up @@ -130,7 +135,10 @@ export function useCurrencyBalances(
}

export function useCurrencyBalance(account?: string, currency?: Currency): CurrencyAmount<Currency> | undefined {
return useCurrencyBalances(account, [currency])[0]
return useCurrencyBalances(
account,
useMemo(() => [currency], [currency])
)[0]
}

// mimics useAllBalances
Expand Down

2 comments on commit a5b152d

@vercel
Copy link

@vercel vercel bot commented on a5b152d Dec 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

widgets – ./

widgets-uniswap.vercel.app
widgets-git-main-uniswap.vercel.app

@vercel
Copy link

@vercel vercel bot commented on a5b152d Dec 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

interface – ./

interface-git-main-uniswap.vercel.app
interface-uniswap.vercel.app

Please sign in to comment.