You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
solid-query 6.0.0-rc.5: useBaseQuery bumps its version signal on observerAdded/observerRemoved, remounting <Show> children in a loop on Solid 2 rc.14+ #12466
useBaseQuery's onCacheEvent (packages/solid-query/src/useBaseQuery.ts on solid-query-v6-pre) calls setVersion(v => v + 1) for every query-cache event whose queryHash matches, without looking at event.type. observerAdded, observerRemoved, observerOptionsUpdated and observerResultsUpdated do not change the query's state, but each one re-runs the result projection.
On Solid 2 rc.14+ this combines with a core issue (solidjs/solid#4540): a non-keyed <Show> gated on q.data remounts its children on every re-run. A child that calls useQuery with the same key adds an observer on mount → observerAdded → version bump → remount → new observer → … an infinite remount loop.
solid-js rc.13 + solid-query 6.0.0-rc.5: 1 mount
solid-js rc.20 + solid-query 6.0.0-rc.5: loop (21 mounts before the guard)
import{render}from"@solidjs/web";import{QueryClient,QueryClientProvider,useQuery}from"@tanstack/solid-query";import{Show}from"solid-js";import{expect,it}from"vitest";constwait=(ms: number)=>newPromise((r)=>setTimeout(r,ms));it("a second observer mounted under a Show gated on the first one's data mounts once",async()=>{constclient=newQueryClient({defaultOptions: {queries: {retry: false,staleTime: Number.POSITIVE_INFINITY}}});letmounts=0;constoptions=()=>({queryKey: ["k"],queryFn: ()=>wait(10).then(()=>1)});functionChild(){mounts++;if(mounts>20)thrownewError("remount loop");useQuery(options);return<p>child</p>;}functionPage(){constq=useQuery(options);return(<Showwhen={q.data!==undefined}><Child/></Show>);}constel=document.createElement("div");constdispose=render(()=>(<QueryClientProviderclient={client}><Page/></QueryClientProvider>),el);awaitwait(100);dispose();expect(mounts).toBe(1);});
expected 21 to be 1 (the guard throws "remount loop").
Suggested fix
Bump version only for events that can change the result (added, removed, updated), not for observer* events. The core issue is the root cause; this avoids the trigger and an unnecessary projection re-run per observer mount/unmount.
Activity