From e98c91c99093dc38ab0c79edcf9adc67c1ac2598 Mon Sep 17 00:00:00 2001 From: Jaco Date: Tue, 6 Dec 2022 09:22:02 +0200 Subject: [PATCH] Adjust events & maps, removing unexpected firing (#8489) --- packages/react-hooks/src/useEventChanges.ts | 6 +++- packages/react-hooks/src/useMapEntries.ts | 31 ++++++++++++++------- packages/react-hooks/src/useMapKeys.ts | 31 ++++++++++++++------- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/packages/react-hooks/src/useEventChanges.ts b/packages/react-hooks/src/useEventChanges.ts index 1935ff5514..7e3699664c 100644 --- a/packages/react-hooks/src/useEventChanges.ts +++ b/packages/react-hooks/src/useEventChanges.ts @@ -36,7 +36,7 @@ function interleave (existing: T[] = [], { added = [], removed delete map[v.toHex()]; }); - return Object + const adjusted = Object .entries(map) .sort((a, b) => // for BN-like objects, we use the built-in compare for sorting @@ -45,6 +45,10 @@ function interleave (existing: T[] = [], { added = [], removed : a[0].localeCompare(b[0]) ) .map(([, v]) => v); + + return adjusted.length !== existing.length || adjusted.find((e, i) => !e.eq(existing[i])) + ? adjusted + : existing; } export function useEventChanges (checks: EventCheck[], filter: (records: EventRecord[], api: ApiPromise, additional?: A) => Changes, startValue?: T[], additional?: A): T[] | undefined { diff --git a/packages/react-hooks/src/useMapEntries.ts b/packages/react-hooks/src/useMapEntries.ts index 5a05090ed8..322d3072f7 100644 --- a/packages/react-hooks/src/useMapEntries.ts +++ b/packages/react-hooks/src/useMapEntries.ts @@ -3,7 +3,9 @@ import type { QueryableStorageEntry } from '@polkadot/api/types'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; + +import { stringify } from '@polkadot/util'; interface Options { transform?: (value: any[]) => T; @@ -12,17 +14,26 @@ interface Options { // FIXME This is generic, we cannot really use createNamedHook export function useMapEntries (entry: QueryableStorageEntry<'promise'> | null | false | undefined, params: unknown[], { transform }: Options = {}, at?: string | null | false): T | undefined { const [state, setState] = useState(); + const checkRef = useRef(null); useEffect((): void => { - entry && ( - at && at !== '0' - ? entry.entriesAt(at, ...params) - : entry.entries(...params) - ).then((entries) => setState( - transform - ? transform(entries) - : entries as unknown as T - )).catch(console.error); + if (entry) { + const check = stringify({ at, params }); + + if (check !== checkRef.current) { + checkRef.current = check; + + ( + at && at !== '0' + ? entry.entriesAt(at, ...params) + : entry.entries(...params) + ).then((entries) => setState( + transform + ? transform(entries) + : entries as unknown as T + )).catch(console.error); + } + } }, [at, entry, params, transform]); return state; diff --git a/packages/react-hooks/src/useMapKeys.ts b/packages/react-hooks/src/useMapKeys.ts index 45d4112b62..3ba6e26038 100644 --- a/packages/react-hooks/src/useMapKeys.ts +++ b/packages/react-hooks/src/useMapKeys.ts @@ -3,7 +3,9 @@ import type { QueryableStorageEntry } from '@polkadot/api/types'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; + +import { stringify } from '@polkadot/util'; interface Options { transform?: (value: any[]) => T[]; @@ -12,17 +14,26 @@ interface Options { // FIXME This is generic, we cannot really use createNamedHook export function useMapKeys (entry: QueryableStorageEntry<'promise'> | null | false | undefined, params: unknown[], { transform }: Options = {}, at?: string | null | false): T[] | undefined { const [state, setState] = useState(); + const checkRef = useRef(null); useEffect((): void => { - entry && ( - at && at !== '0' - ? entry.keysAt(at, ...params) - : entry.keys(...params) - ).then((keys) => setState( - transform - ? transform(keys) - : keys as unknown as T[] - )).catch(console.error); + if (entry) { + const check = stringify({ at, params }); + + if (check !== checkRef.current) { + checkRef.current = check; + + ( + at && at !== '0' + ? entry.keysAt(at, ...params) + : entry.keys(...params) + ).then((keys) => setState( + transform + ? transform(keys) + : keys as unknown as T[] + )).catch(console.error); + } + } }, [at, entry, params, transform]); return state;