diff --git a/packages/solid-query/src/__tests__/createQuery.test.tsx b/packages/solid-query/src/__tests__/createQuery.test.tsx index 02b8dfd2b0..d9855531e9 100644 --- a/packages/solid-query/src/__tests__/createQuery.test.tsx +++ b/packages/solid-query/src/__tests__/createQuery.test.tsx @@ -35,6 +35,7 @@ import { } from './utils' import { vi } from 'vitest' import type { Mock } from 'vitest' +import { reconcile } from 'solid-js/store' describe('createQuery', () => { const queryCache = new QueryCache() @@ -4609,6 +4610,61 @@ describe('createQuery', () => { expect(states).toHaveLength(1) }) + it('The reconcile fn callback should correctly maintain referential equality', async () => { + const key1 = queryKey() + const states: Array> = [] + + function Page() { + const [forceValue, setForceValue] = createSignal(1) + + const state = createQuery(() => ({ + queryKey: key1, + queryFn: async () => { + await sleep(10) + return [1, 2] + }, + select: (res) => res.map((x) => x + 1), + reconcile(oldData, newData) { + return reconcile(newData)(oldData) + }, + })) + + createEffect(() => { + if (state.data) { + states.push(state.data) + } + }) + + const forceUpdate = () => { + setForceValue((prev) => prev + 1) + } + + return ( +
+

Data: {JSON.stringify(state.data)}

+

forceValue: {forceValue}

+ +
+ ) + } + + render(() => ( + + + + )) + await waitFor(() => screen.getByText('Data: [2,3]')) + expect(states).toHaveLength(1) + + fireEvent.click(screen.getByRole('button', { name: /forceUpdate/i })) + + await waitFor(() => screen.getByText('forceValue: 2')) + await waitFor(() => screen.getByText('Data: [2,3]')) + + // effect should not be triggered again due to structural sharing + expect(states).toHaveLength(1) + }) + it('should cancel the query function when there are no more subscriptions', async () => { const key = queryKey() let cancelFn: Mock = vi.fn()