diff --git a/packages/react-components/src/VoteValue.tsx b/packages/react-components/src/VoteValue.tsx index 7cd41e2287..a7464f0c2a 100644 --- a/packages/react-components/src/VoteValue.tsx +++ b/packages/react-components/src/VoteValue.tsx @@ -4,10 +4,10 @@ import { DeriveBalancesAll } from '@polkadot/api-derive/types'; import BN from 'bn.js'; -import React, { useCallback, useEffect, useState, useMemo } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { useApi, useCall } from '@polkadot/react-hooks'; import { BalanceVoting } from '@polkadot/react-query'; -import { isBn } from '@polkadot/util'; +import { BN_ZERO } from '@polkadot/util'; import InputBalance from './InputBalance'; import { useTranslation } from './translate'; @@ -20,37 +20,42 @@ interface Props { } interface ValueState { + maxValue: BN; selectedId?: string | null; - value?: BN; + value: BN; } function VoteValue ({ accountId, autoFocus, isCouncil, onChange }: Props): React.ReactElement | null { const { t } = useTranslation(); const { api } = useApi(); const allBalances = useCall(api.derive.balances.all, [accountId]); - const [{ selectedId, value }, setValue] = useState({}); - const maxVotingBalance = useMemo(() => - isCouncil - ? allBalances?.votingBalance.add(allBalances?.reservedBalance) - : allBalances?.votingBalance - , [allBalances, isCouncil]); + const [{ maxValue, selectedId, value }, setValue] = useState({ maxValue: BN_ZERO, value: BN_ZERO }); useEffect((): void => { // if the set accountId changes and the new balances is for that id, set it - (accountId !== selectedId) && allBalances && allBalances.accountId.eq(accountId) && setValue({ - selectedId: accountId, - value: allBalances.lockedBalance - }); - }, [allBalances, accountId, maxVotingBalance, selectedId]); + allBalances && allBalances.accountId.eq(accountId) && setValue((state) => + state.selectedId !== accountId + ? ({ + maxValue: allBalances.votingBalance.add(isCouncil ? allBalances.reservedBalance : BN_ZERO), + selectedId: accountId, + value: allBalances.lockedBalance + }) + : state + ); + }, [allBalances, accountId, isCouncil]); // only do onChange to parent when the BN value comes in, not our formatted version useEffect((): void => { - isBn(value) && onChange(value); + onChange(value); }, [onChange, value]); const _setValue = useCallback( - (value?: BN) => setValue(({ selectedId }) => ({ selectedId, value })), - [] + (value?: BN) => setValue((state) => + state.selectedId === accountId && value && !value.eq(state.value) + ? ({ ...state, value }) + : state + ), + [accountId] ); const isDisabled = accountId !== selectedId; @@ -58,9 +63,10 @@ function VoteValue ({ accountId, autoFocus, isCouncil, onChange }: Props): React return ( ('The amount that is associated with this vote. This value is is locked for the duration of the vote.')} isDisabled={isDisabled} @@ -73,7 +79,7 @@ function VoteValue ({ accountId, autoFocus, isCouncil, onChange }: Props): React params={accountId} /> } - maxValue={maxVotingBalance} + maxValue={maxValue} onChange={_setValue} /> );