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

fix: memoize more swap (#2950)

* fix: memoize derived swap info

* fix: memoize current block timestamp

* fix: memoize price impact

* fix: memoize debounced value updates

* fix: nits
parent 850a20f6
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { InterfaceTrade, TradeState } from 'state/routing/types'
import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade'
......@@ -24,7 +25,10 @@ export function useBestTrade(
const autoRouterSupported = useAutoRouterSupported()
const isWindowVisible = useIsWindowVisible()
const [debouncedAmount, debouncedOtherCurrency] = useDebounce([amountSpecified, otherCurrency], 200)
const [debouncedAmount, debouncedOtherCurrency] = useDebounce(
useMemo(() => [amountSpecified, otherCurrency], [amountSpecified, otherCurrency]),
200
)
const routingAPITrade = useRoutingAPITrade(
tradeType,
......@@ -56,9 +60,12 @@ export function useBestTrade(
)
// only return gas estimate from api if routing api trade is used
return {
return useMemo(
() => ({
...(useFallback ? bestV3Trade : routingAPITrade),
...(debouncing ? { state: TradeState.SYNCING } : {}),
...(isLoading ? { state: TradeState.LOADING } : {}),
}
}),
[bestV3Trade, debouncing, isLoading, routingAPITrade, useFallback]
)
}
import { useEffect, useState } from 'react'
/**
* Debounces updates to a value.
* Non-primitives *must* wrap the value in useMemo, or the value will be updated due to referential inequality.
*/
// modified from https://usehooks.com/useDebounce/
export default function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
......
......@@ -99,7 +99,10 @@ export function useTokenBalances(
// get the balance for a single token/account combo
export function useTokenBalance(account?: string, token?: Token): CurrencyAmount<Token> | undefined {
const tokenBalances = useTokenBalances(account, [token])
const tokenBalances = useTokenBalances(
account,
useMemo(() => [token], [token])
)
if (!token) return undefined
return tokenBalances[token.address]
}
......@@ -115,7 +118,7 @@ export function useCurrencyBalances(
const tokenBalances = useTokenBalances(account, tokens)
const containsETH: boolean = useMemo(() => currencies?.some((currency) => currency?.isNative) ?? false, [currencies])
const ethBalance = useNativeCurrencyBalances(containsETH ? [account] : [])
const ethBalance = useNativeCurrencyBalances(useMemo(() => (containsETH ? [account] : []), [containsETH, account]))
return useMemo(
() =>
......
......@@ -137,7 +137,10 @@ export default function Swap({ history }: RouteComponentProps) {
const fiatValueInput = useUSDCValue(parsedAmounts[Field.INPUT])
const fiatValueOutput = useUSDCValue(parsedAmounts[Field.OUTPUT])
const priceImpact = routeIsSyncing ? undefined : computeFiatValuePriceImpact(fiatValueInput, fiatValueOutput)
const priceImpact = useMemo(
() => (routeIsSyncing ? undefined : computeFiatValuePriceImpact(fiatValueInput, fiatValueOutput)),
[fiatValueInput, fiatValueOutput, routeIsSyncing]
)
const { onSwitchTokens, onCurrencySelection, onUserInput, onChangeRecipient } = useSwapActionHandlers()
const isValid = !swapInputError
......
......@@ -136,17 +136,26 @@ export function useDerivedSwapInfo(): {
(isExactIn ? outputCurrency : inputCurrency) ?? undefined
)
const currencyBalances = {
const currencyBalances = useMemo(
() => ({
[Field.INPUT]: relevantTokenBalances[0],
[Field.OUTPUT]: relevantTokenBalances[1],
}
}),
[relevantTokenBalances]
)
const currencies: { [field in Field]?: Currency | null } = {
const currencies: { [field in Field]?: Currency | null } = useMemo(
() => ({
[Field.INPUT]: inputCurrency,
[Field.OUTPUT]: outputCurrency,
}
}),
[inputCurrency, outputCurrency]
)
const allowedSlippage = useSwapSlippageTolerance(trade.trade ?? undefined)
const inputError = useMemo(() => {
let inputError: ReactNode | undefined
if (!account) {
inputError = <Trans>Connect Wallet</Trans>
}
......@@ -168,8 +177,6 @@ export function useDerivedSwapInfo(): {
}
}
const allowedSlippage = useSwapSlippageTolerance(trade.trade ?? undefined)
// compare input balance to max input based on version
const [balanceIn, amountIn] = [currencyBalances[Field.INPUT], trade.trade?.maximumAmountIn(allowedSlippage)]
......@@ -177,14 +184,20 @@ export function useDerivedSwapInfo(): {
inputError = <Trans>Insufficient {amountIn.currency.symbol} balance</Trans>
}
return {
return inputError
}, [account, allowedSlippage, currencies, currencyBalances, parsedAmount, to, trade.trade])
return useMemo(
() => ({
currencies,
currencyBalances,
parsedAmount,
inputError,
trade,
allowedSlippage,
}
}),
[allowedSlippage, currencies, currencyBalances, inputError, parsedAmount, trade]
)
}
function parseCurrencyFromURLParameter(urlParam: any): string {
......
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