behaviour of createAsync in hooks - why cached?
I'm trying to get a better understanding on createAsync & query, and weather or not it is an appropriate way to share state.
I created a hook and use it like this.
This works perfectly fine. But I'm confused why the logs appear in the console, but no requests are made. I understood, that the query() cashes for only 5 seconds - so why is it not making requests all the timem even on navigation? I can import the hook and access the data from everywhere simultaneously.
Honestly this is the behaviour i hoped for (its easy to revalidate the cash), but I'd like to fully understand why this works.
Thanks!
❤️
9 Replies
You are showing
useMyHook
but the component is using useAuth
. What is going on in between?
As it stands the behaviour you are describing could be easily explained if you are using the same instance of createAsync
across navigations.Oh, thats a leftover from my actual code. I just edited it, thanks!
Well, I'm using the same instance of the query, but not of the hook, right? I'm using the hook at multiple places, and each hook is a new instance, including the internal createAsync primitive.
query caches for 10-15 seconds, that may explain it
Each createAsync is pulling from the same query, so they’ll only cause a refetch if they’re called 10-15 seconds after the first call
Mh, i just checked, it does not refetch the user, even after 15 seconds or longer
it won’t refetch automatically if that’s what you’re expecting
i hoped it wouldnt, but im still wondering why it doesnt. When I use
const res = createAsync(() => getData());
on PageComponent (Home.tsx) it does refetch on every navigation, right? Why does it not refretch when used inside a hook?Depends if the navigation causes a new instance of createAsync to be created. If not then no refetch will happen on navigate, since nothing will call getData
but every instance of the my hook, (see above, useMyHook) creates a new instance of createAsync as well, and its not triggereing a refetch
Something strange is going on here:
Upon navigation:
- First the reference count is incremented
- then the clean up from the previous subscription runs
This seems out of sequence.
Because of this the reference count check always comes back with
1
so the staleness check is bypassed.
SolidStart basic/TS template. Then
Debugging:
http://localhost:3000/_build/node_modules/.pnpm/@[email protected][email protected]/node_modules/@solidjs/router/dist/data/query.js
but I'd like to fully understand why this works.Basically the way it works right now is that as long as there is at least one
createAsync
(i.e. tracked) reference to the query
the value is assumed to be "fresh".
The whole "5 seconds" limit (PRELOAD_TIMEOUT
) applies to the time that passes between a route preload:
(which presumably is not tracked) and the first tracked reference (createAsync
); i.e. if for whatever reason it takes more than 5 secs between the preload and the first createAsync
then the request is repeated.
During navigation the reference of the previous route hasn't cleared yet, so when the next route registers its createAsync
query
doesn't refresh either.
Aside: The idea behind your useMyHook
function may not be optimal (you export useMyHook
but not getData
).
In SolidStart the goal is to "fetch before you render" so a route would ideally warm up all the query
s necessary for its components in its preload
. That way components connect with their createAsync
s to query
s that are already loading (or have already loaded).
The aim is to hoist data loading all the way up to the route level rather than delaying it until component creation.