From a516aee41be364087a5c95cce413d1acd8d3c7e0 Mon Sep 17 00:00:00 2001 From: Aryan Deora Date: Wed, 17 Jul 2024 15:24:44 -0400 Subject: [PATCH 1/2] fix(solid-query): Fix race condition issues with `createQuery` --- packages/solid-query/src/createBaseQuery.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/solid-query/src/createBaseQuery.ts b/packages/solid-query/src/createBaseQuery.ts index f70e298b99..120b67dd97 100644 --- a/packages/solid-query/src/createBaseQuery.ts +++ b/packages/solid-query/src/createBaseQuery.ts @@ -179,7 +179,11 @@ export function createBaseQuery< const obs = observer() return obs.subscribe((result) => { observerResult = result - queueMicrotask(() => refetch()) + queueMicrotask(() => { + if (unsubscribe) { + refetch() + } + }) }) } From 84ba28aac1220507eb74da6f9a4fbdc32223ff4e Mon Sep 17 00:00:00 2001 From: Aryan Deora Date: Wed, 17 Jul 2024 15:25:41 -0400 Subject: [PATCH 2/2] fix(solid-query): Fix race condition issues with `createQuery` Tests --- .../src/__tests__/createQuery.test.tsx | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/packages/solid-query/src/__tests__/createQuery.test.tsx b/packages/solid-query/src/__tests__/createQuery.test.tsx index 39a08d7580..e20b54fc70 100644 --- a/packages/solid-query/src/__tests__/createQuery.test.tsx +++ b/packages/solid-query/src/__tests__/createQuery.test.tsx @@ -3528,6 +3528,124 @@ describe('createQuery', () => { ]) }) + // See https://github.com/TanStack/query/issues/7711 + it('race condition: should cleanup observers after component that created the query is unmounted #1', async () => { + const key = queryKey() + + function Component() { + let val = 1 + const dataQuery = createQuery(() => ({ + queryKey: [key], + queryFn: () => { + return val++ + }, + })) + + return ( +
+

component

+

data: {String(dataQuery.data)}

+
+ ) + } + + const Outer = () => { + const [showComp, setShowComp] = createSignal(true) + return ( +
+ + {showComp() ? :
not showing
} +
+ ) + } + + const rendered = render(() => ( + + + + )) + + await waitFor(() => rendered.getByText('component')) + fireEvent.click(rendered.getByText('toggle')) + await waitFor(() => rendered.getByText('not showing')) + fireEvent.click(rendered.getByText('toggle')) + await waitFor(() => rendered.getByText('component')) + fireEvent.click(rendered.getByText('toggle')) + await waitFor(() => rendered.getByText('not showing')) + + const entry = queryClient.getQueryCache().find({ + queryKey: [key], + })! + + expect(entry.getObserversCount()).toBe(0) + }) + + // See https://github.com/TanStack/query/issues/7711 + it('race condition: should cleanup observers after component that created the query is unmounted #2', async () => { + const key = queryKey() + + function Component() { + let val = 1 + const dataQuery = createQuery(() => ({ + queryKey: [key], + queryFn: () => { + return val++ + }, + })) + + return ( +
+

component

+

data: {String(dataQuery.data)}

+
+ ) + } + + const Outer = () => { + const [showComp, setShowComp] = createSignal(true) + return ( +
+ + {showComp() ? :
not showing
} +
+ ) + } + + const rendered = render(() => ( + + + + )) + + await waitFor(() => rendered.getByText('component')) + fireEvent.click(rendered.getByText('toggle')) + await waitFor(() => rendered.getByText('not showing')) + fireEvent.click(rendered.getByText('toggle')) + await waitFor(() => rendered.getByText('component')) + fireEvent.click(rendered.getByText('toggle')) + await waitFor(() => rendered.getByText('not showing')) + + const entry = queryClient.getQueryCache().find({ + queryKey: [key], + })! + + expect(entry.getObserversCount()).toBe(0) + }) + it('should mark query as fetching, when using initialData', async () => { const key = queryKey() const results: Array> = []