diff --git a/src/react/internal/cache/QueryReference.ts b/src/react/internal/cache/QueryReference.ts index ae995db3209..83a4398703b 100644 --- a/src/react/internal/cache/QueryReference.ts +++ b/src/react/internal/cache/QueryReference.ts @@ -79,7 +79,7 @@ export interface PreloadedQueryRef< } interface InternalQueryReferenceOptions { - onDispose?: () => void; + onDispose: (ref: InternalQueryReference) => void; autoDisposeTimeoutMs?: number; } @@ -209,9 +209,10 @@ export class InternalQueryReference< this.dispose = this.dispose.bind(this); this.observable = observable; - if (options.onDispose) { - this.onDispose = options.onDispose; - } + this.onDispose = () => { + clearTimeout(this.autoDisposeTimeoutId); + options.onDispose?.(this); + }; this.setResult(); this.subscribeToQuery(); @@ -351,7 +352,7 @@ export class InternalQueryReference< return this.initiateFetch(this.observable.fetchMore(options)); } - private dispose() { + public dispose() { this.subscription.unsubscribe(); } diff --git a/src/react/internal/cache/SuspenseCache.ts b/src/react/internal/cache/SuspenseCache.ts index 58bace2fb31..4ca49492259 100644 --- a/src/react/internal/cache/SuspenseCache.ts +++ b/src/react/internal/cache/SuspenseCache.ts @@ -43,15 +43,30 @@ export class SuspenseCache { >(cacheKey: CacheKey, createObservable: () => ObservableQuery) { const ref = this.queryRefs.lookupArray(cacheKey) as { current?: InternalQueryReference; + disposeTimeout?: ReturnType; }; if (!ref.current) { ref.current = new InternalQueryReference(createObservable(), { autoDisposeTimeoutMs: this.options.autoDisposeTimeoutMs, - onDispose: () => { + onDispose: (internalRef) => { + if (internalRef !== ref.current) { + return; + } delete ref.current; + if (ref.disposeTimeout) { + clearTimeout(ref.disposeTimeout); + delete ref.disposeTimeout; + } }, }); + } else if (ref.current.promise.status === "rejected") { + if (ref.disposeTimeout) { + clearTimeout(ref.disposeTimeout); + } + ref.disposeTimeout = setTimeout(() => { + ref.current?.dispose(); + }, 1000); } return ref.current;