diff --git a/.changeset/legal-signs-call.md b/.changeset/legal-signs-call.md new file mode 100644 index 00000000000..0df330d08ec --- /dev/null +++ b/.changeset/legal-signs-call.md @@ -0,0 +1,7 @@ +--- +'@tanstack/solid-query-persist-client': patch +'@tanstack/solid-query-devtools': patch +'@tanstack/solid-query': patch +--- + +refactor: solid 2 reactivity compliance diff --git a/packages/solid-query/src/__tests__/mutationOptions.test.tsx b/packages/solid-query/src/__tests__/mutationOptions.test.tsx index f86d9fff489..a90e8a3bce7 100644 --- a/packages/solid-query/src/__tests__/mutationOptions.test.tsx +++ b/packages/solid-query/src/__tests__/mutationOptions.test.tsx @@ -48,7 +48,7 @@ describe('mutationOptions', () => { function Mutation() { const isMutating = useIsMutating() - const { mutate } = useMutation(() => mutationOpts) + const mutation = useMutation(() => mutationOpts) createRenderEffect(isMutating, (count) => { isMutatingArray.push(count) @@ -56,7 +56,7 @@ describe('mutationOptions', () => { return (
- +
) } @@ -85,7 +85,7 @@ describe('mutationOptions', () => { function Mutation() { const isMutating = useIsMutating() - const { mutate } = useMutation(() => mutationOpts) + const mutation = useMutation(() => mutationOpts) createRenderEffect(isMutating, (count) => { isMutatingArray.push(count) @@ -93,7 +93,7 @@ describe('mutationOptions', () => { return (
- +
) } @@ -126,8 +126,8 @@ describe('mutationOptions', () => { function Mutation() { const isMutating = useIsMutating() - const { mutate: mutate1 } = useMutation(() => mutationOpts1) - const { mutate: mutate2 } = useMutation(() => mutationOpts2) + const mutation1 = useMutation(() => mutationOpts1) + const mutation2 = useMutation(() => mutationOpts2) createRenderEffect(isMutating, (count) => { isMutatingArray.push(count) @@ -135,8 +135,8 @@ describe('mutationOptions', () => { return (
- - + +
) } @@ -171,8 +171,8 @@ describe('mutationOptions', () => { const isMutating = useIsMutating(() => ({ mutationKey: mutationOpts1.mutationKey, })) - const { mutate: mutate1 } = useMutation(() => mutationOpts1) - const { mutate: mutate2 } = useMutation(() => mutationOpts2) + const mutation1 = useMutation(() => mutationOpts1) + const mutation2 = useMutation(() => mutationOpts2) createRenderEffect(isMutating, (count) => { isMutatingArray.push(count) @@ -180,8 +180,8 @@ describe('mutationOptions', () => { return (
- - + +
) } @@ -211,11 +211,11 @@ describe('mutationOptions', () => { }) function Mutation() { - const { mutate } = useMutation(() => mutationOpts) + const mutation = useMutation(() => mutationOpts) return (
- +
) } @@ -252,11 +252,11 @@ describe('mutationOptions', () => { }) function Mutation() { - const { mutate } = useMutation(() => mutationOpts) + const mutation = useMutation(() => mutationOpts) return (
- +
) } @@ -297,13 +297,13 @@ describe('mutationOptions', () => { }) function Mutation() { - const { mutate: mutate1 } = useMutation(() => mutationOpts1) - const { mutate: mutate2 } = useMutation(() => mutationOpts2) + const mutation1 = useMutation(() => mutationOpts1) + const mutation2 = useMutation(() => mutationOpts2) return (
- - + +
) } @@ -345,13 +345,13 @@ describe('mutationOptions', () => { }) function Mutation() { - const { mutate: mutate1 } = useMutation(() => mutationOpts1) - const { mutate: mutate2 } = useMutation(() => mutationOpts2) + const mutation1 = useMutation(() => mutationOpts1) + const mutation2 = useMutation(() => mutationOpts2) return (
- - + +
) } @@ -398,7 +398,7 @@ describe('mutationOptions', () => { }) function Mutation() { - const { mutate } = useMutation(() => mutationOpts) + const mutation = useMutation(() => mutationOpts) const states = useMutationState(() => ({ filters: { mutationKey: mutationOpts.mutationKey, status: 'success' }, })) @@ -412,7 +412,7 @@ describe('mutationOptions', () => { return (
- +
) } @@ -441,7 +441,7 @@ describe('mutationOptions', () => { }) function Mutation() { - const { mutate } = useMutation(() => mutationOpts) + const mutation = useMutation(() => mutationOpts) const states = useMutationState(() => ({ filters: { status: 'success' }, })) @@ -455,7 +455,7 @@ describe('mutationOptions', () => { return (
- +
) } @@ -488,8 +488,8 @@ describe('mutationOptions', () => { }) function Mutation() { - const { mutate: mutate1 } = useMutation(() => mutationOpts1) - const { mutate: mutate2 } = useMutation(() => mutationOpts2) + const mutation1 = useMutation(() => mutationOpts1) + const mutation2 = useMutation(() => mutationOpts2) const states = useMutationState(() => ({ filters: { status: 'success' }, })) @@ -503,8 +503,8 @@ describe('mutationOptions', () => { return (
- - + +
) } @@ -539,8 +539,8 @@ describe('mutationOptions', () => { }) function Mutation() { - const { mutate: mutate1 } = useMutation(() => mutationOpts1) - const { mutate: mutate2 } = useMutation(() => mutationOpts2) + const mutation1 = useMutation(() => mutationOpts1) + const mutation2 = useMutation(() => mutationOpts2) const states = useMutationState(() => ({ filters: { mutationKey: mutationOpts1.mutationKey, status: 'success' }, })) @@ -554,8 +554,8 @@ describe('mutationOptions', () => { return (
- - + +
) } diff --git a/packages/solid-query/src/__tests__/useIsMutating.test.tsx b/packages/solid-query/src/__tests__/useIsMutating.test.tsx index 679252cca44..b08231aa33e 100644 --- a/packages/solid-query/src/__tests__/useIsMutating.test.tsx +++ b/packages/solid-query/src/__tests__/useIsMutating.test.tsx @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { fireEvent, render } from '@solidjs/testing-library' -import { Show, createRenderEffect, createSignal } from 'solid-js' +import { Show, createRenderEffect, createSignal, untrack } from 'solid-js' import * as QueryCore from '@tanstack/query-core' import { sleep } from '@tanstack/query-test-utils' import { @@ -35,18 +35,18 @@ describe('useIsMutating', () => { } function Mutations() { - const { mutate: mutate1 } = useMutation(() => ({ + const mutation1 = useMutation(() => ({ mutationKey: ['mutation1'], mutationFn: () => sleep(150).then(() => 'data'), })) - const { mutate: mutate2 } = useMutation(() => ({ + const mutation2 = useMutation(() => ({ mutationKey: ['mutation2'], mutationFn: () => sleep(50).then(() => 'data'), })) - mutate1() + untrack(() => mutation1.mutate()) setActTimeout(() => { - mutate2() + mutation2.mutate() }, 50) return null @@ -87,18 +87,18 @@ describe('useIsMutating', () => { } function Page() { - const { mutate: mutate1 } = useMutation(() => ({ + const mutation1 = useMutation(() => ({ mutationKey: ['mutation1'], mutationFn: () => sleep(100).then(() => 'data'), })) - const { mutate: mutate2 } = useMutation(() => ({ + const mutation2 = useMutation(() => ({ mutationKey: ['mutation2'], mutationFn: () => sleep(100).then(() => 'data'), })) setActTimeout(() => { - mutate1() - mutate2() + mutation1.mutate() + mutation2.mutate() }, 10) return @@ -135,18 +135,18 @@ describe('useIsMutating', () => { } function Page() { - const { mutate: mutate1 } = useMutation(() => ({ + const mutation1 = useMutation(() => ({ mutationKey: ['mutation1'], mutationFn: () => sleep(100).then(() => 'data'), })) - const { mutate: mutate2 } = useMutation(() => ({ + const mutation2 = useMutation(() => ({ mutationKey: ['mutation2'], mutationFn: () => sleep(100).then(() => 'data'), })) setActTimeout(() => { - mutate1() - mutate2() + mutation1.mutate() + mutation2.mutate() }, 10) return @@ -170,7 +170,7 @@ describe('useIsMutating', () => { function Page() { const isMutating = useIsMutating(undefined, () => queryClient) - const { mutate } = useMutation( + const mutation = useMutation( () => ({ mutationKey: ['mutation1'], mutationFn: () => sleep(20).then(() => 'data'), @@ -179,7 +179,7 @@ describe('useIsMutating', () => { ) setActTimeout(() => { - mutate() + mutation.mutate() }, 10) return ( @@ -225,12 +225,12 @@ describe('useIsMutating', () => { function Page() { const [mounted, setMounted] = createSignal(true) - const { mutate: mutate1 } = useMutation(() => ({ + const mutation1 = useMutation(() => ({ mutationKey: ['mutation1'], mutationFn: () => sleep(10).then(() => 'data'), })) - mutate1() + untrack(() => mutation1.mutate()) return (
diff --git a/packages/solid-query/src/__tests__/useQuery.test.tsx b/packages/solid-query/src/__tests__/useQuery.test.tsx index c39cbba0662..ac948a48c6b 100644 --- a/packages/solid-query/src/__tests__/useQuery.test.tsx +++ b/packages/solid-query/src/__tests__/useQuery.test.tsx @@ -19,6 +19,7 @@ import { createTrackedEffect, reconcile, snapshot, + untrack, } from 'solid-js' import { fireEvent, render } from '@solidjs/testing-library' import { @@ -1153,7 +1154,7 @@ describe('useQuery', () => { } }) - const { refetch } = state + const refetch = untrack(() => state.refetch) return (
@@ -1240,7 +1241,7 @@ describe('useQuery', () => { }, ) - const { refetch } = state + const refetch = untrack(() => state.refetch) return (
@@ -2263,12 +2264,12 @@ describe('useQuery', () => { const key = queryKey() function Page() { - const { status } = useQuery(() => ({ + const state = useQuery(() => ({ queryKey: key, queryFn: () => sleep(10).then(() => 'test'), })) - return
status: {status}
+ return
status: {state.status}
} const rendered = render(() => ( @@ -2289,7 +2290,7 @@ describe('useQuery', () => { .mockReturnValue('data') function Page() { - const { data = 'default' } = useQuery(() => ({ + const state = useQuery(() => ({ queryKey: key, queryFn, enabled: false, @@ -2297,7 +2298,7 @@ describe('useQuery', () => { return (
-

{data}

+

{state.data ?? 'default'}

) } @@ -4234,13 +4235,13 @@ describe('useQuery', () => { queryFn.mockImplementation(() => 'data') function Page() { - const { fetchStatus } = useQuery(() => ({ + const state = useQuery(() => ({ queryKey: key, queryFn, enabled: false, })) - return
fetchStatus: {fetchStatus}
+ return
fetchStatus: {state.fetchStatus}
} const rendered = render(() => ( @@ -5337,7 +5338,7 @@ describe('useQuery', () => { }, ) - const { refetch } = state + const refetch = untrack(() => state.refetch) return (
diff --git a/packages/solid-query/src/useBaseQuery.ts b/packages/solid-query/src/useBaseQuery.ts index 6f3c3353c26..3eb14e71f52 100644 --- a/packages/solid-query/src/useBaseQuery.ts +++ b/packages/solid-query/src/useBaseQuery.ts @@ -11,6 +11,7 @@ import { reconcile, refresh, snapshot, + untrack, } from 'solid-js' import { useQueryClient } from './QueryClientProvider' import { useIsRestoring } from './isRestoring' @@ -174,7 +175,7 @@ export function useBaseQuery< return defaultOptions }) - const observer = new Observer(client(), defaultedOptions()) + const observer = untrack(() => new Observer(client(), defaultedOptions())) // Track options reactively so the queryResource memo re-runs on change. const trackedDefaultedOptions = createMemo(() => defaultedOptions()) @@ -189,7 +190,10 @@ export function useBaseQuery< }, ) - let observerResult = observer.getOptimisticResult(defaultedOptions()) + let observerResult = untrack(() => + observer.getOptimisticResult(defaultedOptions()), + ) + const [state, setState] = createStore>( _stripFnsForSSR(observerResult), ) diff --git a/packages/solid-query/src/useIsFetching.ts b/packages/solid-query/src/useIsFetching.ts index e118a5d0762..f24c51f9d3e 100644 --- a/packages/solid-query/src/useIsFetching.ts +++ b/packages/solid-query/src/useIsFetching.ts @@ -1,4 +1,4 @@ -import { createMemo, createSignal, onCleanup } from 'solid-js' +import { createMemo, createSignal, onCleanup, untrack } from 'solid-js' import { useQueryClient } from './QueryClientProvider' import type { QueryFilters } from '@tanstack/query-core' import type { QueryClient } from './QueryClient' @@ -11,11 +11,16 @@ export function useIsFetching( const client = createMemo(() => useQueryClient(queryClient?.())) const queryCache = createMemo(() => client().getQueryCache()) - const [fetches, setFetches] = createSignal(client().isFetching(filters?.())) + const [fetches, setFetches] = createSignal( + untrack(() => client().isFetching(filters?.())), + { pureWrite: true }, + ) - const unsubscribe = queryCache().subscribe(() => { - setFetches(client().isFetching(filters?.())) - }) + const unsubscribe = untrack(() => + queryCache().subscribe(() => { + setFetches(client().isFetching(filters?.())) + }), + ) onCleanup(unsubscribe) diff --git a/packages/solid-query/src/useIsMutating.ts b/packages/solid-query/src/useIsMutating.ts index 57ec870e459..782f0da96cd 100644 --- a/packages/solid-query/src/useIsMutating.ts +++ b/packages/solid-query/src/useIsMutating.ts @@ -1,4 +1,4 @@ -import { createMemo, createSignal, onCleanup } from 'solid-js' +import { createMemo, createSignal, onCleanup, untrack } from 'solid-js' import { useQueryClient } from './QueryClientProvider' import type { MutationFilters } from '@tanstack/query-core' import type { QueryClient } from './QueryClient' @@ -12,12 +12,15 @@ export function useIsMutating( const mutationCache = createMemo(() => client().getMutationCache()) const [mutations, setMutations] = createSignal( - client().isMutating(filters?.()), + untrack(() => client().isMutating(filters?.())), + { pureWrite: true }, ) - const unsubscribe = mutationCache().subscribe((_result) => { - setMutations(client().isMutating(filters?.())) - }) + const unsubscribe = untrack(() => + mutationCache().subscribe((_result) => { + setMutations(client().isMutating(filters?.())) + }), + ) onCleanup(unsubscribe) diff --git a/packages/solid-query/src/useMutation.ts b/packages/solid-query/src/useMutation.ts index f2d3a24e5af..5f4eceb79c1 100644 --- a/packages/solid-query/src/useMutation.ts +++ b/packages/solid-query/src/useMutation.ts @@ -4,6 +4,7 @@ import { createRenderEffect, createStore, onCleanup, + untrack, } from 'solid-js' import { useQueryClient } from './QueryClientProvider' import type { DefaultError } from '@tanstack/query-core' @@ -27,17 +28,21 @@ export function useMutation< ): UseMutationResult { const client = createMemo(() => useQueryClient(queryClient?.())) - const observer = new MutationObserver< - TData, - TError, - TVariables, - TOnMutateResult - >(client(), options()) + const observer = untrack( + () => + new MutationObserver( + client(), + options(), + ), + ) // Track options changes and update observer - createMemo(() => { - observer.setOptions(options()) - }) + createRenderEffect( + () => options(), + (opts) => { + observer.setOptions(opts) + }, + ) const mutate: UseMutateFunction< TData, @@ -48,12 +53,13 @@ export function useMutation< observer.mutate(variables, mutateOptions).catch(noop) } + const initialResult = untrack(() => observer.getCurrentResult()) const [state, setState] = createStore< UseMutationResult >({ - ...observer.getCurrentResult(), + ...initialResult, mutate, - mutateAsync: observer.getCurrentResult().mutate, + mutateAsync: initialResult.mutate, }) const unsubscribe = observer.subscribe((result) => { diff --git a/packages/solid-query/src/useMutationState.ts b/packages/solid-query/src/useMutationState.ts index f89319ea604..0519fd1013e 100644 --- a/packages/solid-query/src/useMutationState.ts +++ b/packages/solid-query/src/useMutationState.ts @@ -1,4 +1,4 @@ -import { createMemo, createSignal, onCleanup } from 'solid-js' +import { createMemo, createSignal, onCleanup, untrack } from 'solid-js' import { replaceEqualDeep } from '@tanstack/query-core' import { useQueryClient } from './QueryClientProvider' import type { @@ -35,18 +35,21 @@ export function useMutationState( const mutationCache = createMemo(() => client().getMutationCache()) const [result, setResult] = createSignal( - getResult(mutationCache(), options()), + untrack(() => getResult(mutationCache(), options())), + { pureWrite: true }, ) - const unsubscribe = mutationCache().subscribe(() => { - setResult((prev) => { - const nextResult = replaceEqualDeep( - prev, - getResult(mutationCache(), options()), - ) - return prev === nextResult ? prev : nextResult - }) - }) + const unsubscribe = untrack(() => + mutationCache().subscribe(() => { + setResult((prev) => { + const nextResult = replaceEqualDeep( + prev, + getResult(mutationCache(), options()), + ) + return prev === nextResult ? prev : nextResult + }) + }), + ) onCleanup(unsubscribe) diff --git a/packages/solid-query/src/useQueries.ts b/packages/solid-query/src/useQueries.ts index ee33149bd65..8582b8ecf2a 100644 --- a/packages/solid-query/src/useQueries.ts +++ b/packages/solid-query/src/useQueries.ts @@ -6,6 +6,7 @@ import { merge, onCleanup, reconcile, + untrack, } from 'solid-js' import { useQueryClient } from './QueryClientProvider' import { useIsRestoring } from './isRestoring' @@ -205,20 +206,25 @@ export function useQueries< ), ) - const observer = new QueriesObserver( - client(), - defaultedQueries(), - queriesOptions().combine - ? ({ - combine: queriesOptions().combine, - } as QueriesObserverOptions) - : undefined, + const observer = untrack( + () => + new QueriesObserver( + client(), + defaultedQueries(), + queriesOptions().combine + ? ({ + combine: queriesOptions().combine, + } as QueriesObserverOptions) + : undefined, + ), ) // Get initial optimistic result - const [, getCombinedResult] = observer.getOptimisticResult( - defaultedQueries(), - (queriesOptions() as QueriesObserverOptions).combine, + const [, getCombinedResult] = untrack(() => + observer.getOptimisticResult( + defaultedQueries(), + (queriesOptions() as QueriesObserverOptions).combine, + ), ) const initialResult = getCombinedResult()