TanStack Query vs Solid Router

I'm looking to use Solidjs for a production app and have a question about a library I typically reach for (TanStack Query) for my SPAs and some of the built-in APIs for Solid Router: query + createAsync. Is there any reason to use TanStack when Solid Router comes with those built-in? Just wondering if there is something I'm missing because, the query + createAsync combination if I'm not mistaken provides a lot of the same benefits that TanStack does with request de-deduping and caching by key. Wondering if there are other gaps present that I am not privy to (e.g. easy request refetching/polling on interval or conditional fetching like the enabled field from TanStack Query). For the visually inclined -- the question is what is the recommendation between these two options and the pros/cons of each: Option 1:
import { createQuery } from "@tanstack/solid-query";

function SomeComponent() {
const query = createQuery(() => ({
queryKey: ["userSession"],
queryFn: async () => {
const response = await fetch(...);
if (!response.ok) throw new Error("Failed to fetch data");
return response.json()
},
enabled: true,
refetchInterval: 5000,
}));
}
import { createQuery } from "@tanstack/solid-query";

function SomeComponent() {
const query = createQuery(() => ({
queryKey: ["userSession"],
queryFn: async () => {
const response = await fetch(...);
if (!response.ok) throw new Error("Failed to fetch data");
return response.json()
},
enabled: true,
refetchInterval: 5000,
}));
}
VS Option 2:
import { createAsync, query } from "@solidjs/router";
const getUserSession = query(() => fetch(...), "userSession");

function SomeComponent() {
const session = createAsync(() => getUserSession());
// do stuff ...
}
import { createAsync, query } from "@solidjs/router";
const getUserSession = query(() => fetch(...), "userSession");

function SomeComponent() {
const session = createAsync(() => getUserSession());
// do stuff ...
}
P.S. Just throwing it out there but, man, Option 2 look really good haha
11 Replies
peerreynders
peerreynders2mo ago
SolidStart's query is deliberately "bare-bones" as it is meant to be "one primitive", not a "bag of features". So the biggest risk is expecting solid-query features when just going plain query. Only you can decide whether you can do without solid-query's breadth of features, so it's important to know the limitations of the query approach. I recently described the capabilities of query as I see them (and as someone who has never used TanStack Query) here https://discord.com/channels/722131463138705510/1330302780250001449/1330366296956735582 Perhaps that may help you assess whether query is good enough for you.
MaveriX89
MaveriX89OP2mo ago
@peerreynders appreciate the link to your write up! Question for you, what does polling look like with Solid Router query ? Like if I'm pairing a query with createAsync, at what level do I apply the setInterval to poll and refetch the data (or I suppose in this case, revalidate the query cache key)? Maybe I just answered my own question there? Haha! As in, do I invoke revalidate within some setInterval that lives in a createEffect?
peerreynders
peerreynders2mo ago
There is no need to put setInterval inside a createEffect.
MaveriX89
MaveriX89OP2mo ago
That was the React dev in me speaking :Laughing_Facepalm: I've been conditioned to put intervals and their cleanup in effect blocks by default Aside from that detail, am I on the right mental track in what the polling/refetch pattern is supposed to be there when using query + createAsync ? Just revalidate on an interval?
peerreynders
peerreynders2mo ago
I guess the question is: can your data change apart from your actions?
MaveriX89
MaveriX89OP2mo ago
Yeah, this is basically a pseudo-realtime use case. Instead of the extreme case (using Websockets), just poll for data every 5 seconds.
peerreynders
peerreynders2mo ago
SSE isn't that extreme 😁
GitHub
GitHub - peerreynders/solid-start-sse-chat: Basic Chat demonstratio...
Basic Chat demonstration with server-sent events (SSE) - peerreynders/solid-start-sse-chat
peerreynders
peerreynders2mo ago
I guess solid-query handles it nice and centralized. I assume it only polls while anyone is actually consuming the query.
MaveriX89
MaveriX89OP2mo ago
Yeah, that's correct. You only have to specify a refetchInterval It has some really nice refetch helpers in general:
refetchInterval,
refetchIntervalInBackground,
refetchOnMount,
refetchOnReconnect,
refetchOnWindowFocus,
refetchInterval,
refetchIntervalInBackground,
refetchOnMount,
refetchOnReconnect,
refetchOnWindowFocus,
peerreynders
peerreynders2mo ago
Would seem a bit silly to have the polling on the component level. If you need that type of a refetch I'd lean towards handling that via context. That way you can reference count with useContext/disposeContext and turn off the polling when nobody is listening. The context would only expose the reactive result; unfortunately its the suspense boundary above the provider that would be triggered (which doesn't matter if you are using transitions).
MaveriX89
MaveriX89OP2mo ago
Hmm, I'm not sure if I would characterize it that way. I think it's more about the granular control of configuring a query to be a "polling query" at the call-site or point of invocation which is what Solid Query provides. I suppose the equivalent would be along the lines if createAsync (which consumes a query) would have some configuration option built-in to refetch the query on some interval

Did you find this page helpful?