Use mountedref for parachain hooks

This commit is contained in:
Jaco Greeff 2021-06-11 19:55:27 +03:00
parent 65e70df191
commit e94273186a
No known key found for this signature in database
GPG Key ID: 270FB2D05A05357C
3 changed files with 36 additions and 28 deletions

View File

@ -7,7 +7,7 @@ import type { Balance, EventRecord, ParaId } from '@polkadot/types/interfaces';
import { useCallback, useEffect, useState } from 'react';
import { useAccounts, useApi, useEventTrigger } from '@polkadot/react-hooks';
import { useAccounts, useApi, useEventTrigger, useIsMountedRef } from '@polkadot/react-hooks';
import { encodeAddress } from '@polkadot/util-crypto';
interface Contributions {
@ -78,6 +78,7 @@ function extractDelta (api: ApiPromise, records: EventRecord[], { contributorsMa
function useMyContributions (paraId: ParaId, childKey: string, keys: string[]): Record<string, Balance> {
const { api } = useApi();
const { allAccountsHex } = useAccounts();
const mountedRef = useIsMountedRef();
const [state, setState] = useState<Record<string, Balance>>({});
const trigger = useEventTrigger([
@ -94,21 +95,23 @@ function useMyContributions (paraId: ParaId, childKey: string, keys: string[]):
if (trigger && keys.length) {
Promise
.all(keys.map((k) => api.rpc.childstate.getStorage(childKey, k)))
.then((values) => setState(
values
.map((v) => api.createType('Option<StorageData>', v))
.map((o) =>
o.isSome
? api.createType('Balance', o.unwrap())
: api.createType('Balance')
)
.reduce((all, b, index) => ({ ...all, [keys[index]]: b }), {})
))
.then((values) =>
mountedRef.current && setState(
values
.map((v) => api.createType('Option<StorageData>', v))
.map((o) =>
o.isSome
? api.createType('Balance', o.unwrap())
: api.createType('Balance')
)
.reduce((all, b, index) => ({ ...all, [keys[index]]: b }), {})
)
)
.catch(console.error);
} else {
setState({});
}
}, [api, childKey, keys, trigger]);
}, [api, childKey, keys, mountedRef, trigger]);
return state;
}
@ -116,6 +119,7 @@ function useMyContributions (paraId: ParaId, childKey: string, keys: string[]):
export default function useContributions (paraId: ParaId, childKey: string): Result {
const { api } = useApi();
const { allAccountsHex } = useAccounts();
const mountedRef = useIsMountedRef();
const [state, _setState] = useState<Result>(() => NO_CONTRIB);
const myContributions = useMyContributions(paraId, childKey, state.myAccountsHex);
@ -164,11 +168,11 @@ export default function useContributions (paraId: ParaId, childKey: string): Res
// first just adjust deltas
useEffect((): void => {
triggerDelta && triggerDelta.events.length &&
mountedRef.current && triggerDelta && triggerDelta.events.length &&
setState(triggerDelta.blockHash, (prev) =>
extractDelta(api, triggerDelta.events, prev, allAccountsHex, api.registry.chainSS58)
);
}, [api, allAccountsHex, setState, triggerDelta]);
}, [api, allAccountsHex, mountedRef, setState, triggerDelta]);
// refreshing the whole map, all keys
useEffect((): void => {
@ -176,12 +180,12 @@ export default function useContributions (paraId: ParaId, childKey: string): Res
api.rpc.childstate
.getKeys(childKey, '0x')
.then((keys) =>
setState(triggerAll.blockHash, (prev) =>
mountedRef.current && setState(triggerAll.blockHash, (prev) =>
extractContributors(keys, prev, allAccountsHex, api.registry.chainSS58)
)
)
.catch(console.error);
}, [allAccountsHex, api, childKey, setState, triggerAll]);
}, [allAccountsHex, api, childKey, mountedRef, setState, triggerAll]);
// update when the contribution amounts have changed
useEffect((): void => {

View File

@ -9,7 +9,7 @@ import type { Campaign, Campaigns } from './types';
import BN from 'bn.js';
import { useEffect, useState } from 'react';
import { useApi, useBestNumber, useCall, useEventTrigger, useMapKeys } from '@polkadot/react-hooks';
import { useApi, useBestNumber, useCall, useEventTrigger, useIsMountedRef, useMapKeys } from '@polkadot/react-hooks';
import { BN_ZERO, u8aConcat, u8aToHex } from '@polkadot/util';
import { blake2AsU8a, encodeAddress } from '@polkadot/util-crypto';
@ -166,6 +166,7 @@ function extractFundIds (keys: StorageKey<[ParaId]>[]): ParaId[] {
export default function useFunds (): Campaigns {
const { api } = useApi();
const bestNumber = useBestNumber();
const mountedRef = useIsMountedRef();
const trigger = useEventTrigger([api.events.crowdloan?.Created]);
const paraIds = useMapKeys(api.query.crowdloan?.funds, { at: trigger.blockHash, transform: extractFundIds });
const campaigns = useCall<Campaign[]>(api.query.crowdloan?.funds.multi, [paraIds], optFundMulti);
@ -174,10 +175,10 @@ export default function useFunds (): Campaigns {
// here we manually add the actual ending status and calculate the totals
useEffect((): void => {
bestNumber && campaigns && leases && setResult((prev) =>
mountedRef.current && bestNumber && campaigns && leases && setResult((prev) =>
createResult(bestNumber, api.consts.crowdloan.minContribution as BlockNumber, campaigns, leases, prev)
);
}, [api, bestNumber, campaigns, leases]);
}, [api, bestNumber, campaigns, leases, mountedRef]);
return result;
}

View File

@ -8,7 +8,7 @@ import type { AuctionInfo, WinnerData, Winning } from './types';
import BN from 'bn.js';
import { useEffect, useRef, useState } from 'react';
import { useApi, useBestNumber, useCall, useEventTrigger } from '@polkadot/react-hooks';
import { useApi, useBestNumber, useCall, useEventTrigger, useIsMountedRef } from '@polkadot/react-hooks';
import { BN_ONE, BN_ZERO, u8aEq } from '@polkadot/util';
import { CROWD_PREFIX } from './constants';
@ -123,6 +123,7 @@ function mergeFirst (ranges: [number, number][], auctionInfo: AuctionInfo, prev:
export default function useWinningData (auctionInfo?: AuctionInfo): Winning[] | undefined {
const { api } = useApi();
const mountedRef = useIsMountedRef();
const ranges = useLeaseRanges();
const [result, setResult] = useState<Winning[] | undefined>();
const bestNumber = useBestNumber();
@ -133,17 +134,17 @@ export default function useWinningData (auctionInfo?: AuctionInfo): Winning[] |
// should be fired once, all entries as an initial round
useEffect((): void => {
auctionInfo && initialEntries && setResult(
mountedRef.current && auctionInfo && initialEntries && setResult(
extractData(ranges, auctionInfo, initialEntries)
);
}, [auctionInfo, initialEntries, ranges]);
}, [auctionInfo, initialEntries, mountedRef, ranges]);
// when block 0 changes, update (typically in non-ending-period, static otherwise)
useEffect((): void => {
auctionInfo && optFirstData && setResult((prev) =>
mountedRef.current && auctionInfo && optFirstData && setResult((prev) =>
mergeFirst(ranges, auctionInfo, prev, optFirstData)
);
}, [auctionInfo, optFirstData, ranges]);
}, [auctionInfo, optFirstData, mountedRef, ranges]);
// on a bid event, get the new entry (assuming the event really triggered, i.e. not just a block)
// and add it to the list when not duplicated. Additionally we cleanup after ourselves when endBlock
@ -156,12 +157,14 @@ export default function useWinningData (auctionInfo?: AuctionInfo): Winning[] |
api.query.auctions
?.winning<Option<WinningData>>(blockOffset)
.then((optCurrent) => setResult((prev) =>
mergeCurrent(ranges, auctionInfo, prev, optCurrent, blockOffset)
))
.then((optCurrent) =>
mountedRef.current && setResult((prev) =>
mergeCurrent(ranges, auctionInfo, prev, optCurrent, blockOffset)
)
)
.catch(console.error);
}
}, [api, bestNumber, auctionInfo, ranges, trigger, triggerRef]);
}, [api, bestNumber, auctionInfo, mountedRef, ranges, trigger, triggerRef]);
return result;
}