-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Investigation: fine-grained async control over caching behaviour #4693
Comments
Here are the cache insights from my lib: The
The I hope these insights provide any help. Im not linking my lib to avoid being targeted as an ad. |
One thing we could do is add an It could be async, and when something other than
Not sure this is possible or desired.
This is what the In combination with #4687 , we could so something like this:
|
@TkDodo I think this topic connect to the one we have discussed previously. Potentially we could introduce a function persister(context, queryFn, persisterOptions) {
// 1. Check if data in `QueryCache` for given `queryKey` exists (means it's been restored already or fetched). If yes, then we skip the persistance layer logic and move to point 4
// 2. Query the persistance layer for stored data by `context.queryKey`
// 3. If stored data matched the `predicate` or `staleTime` from `persisterOptions` just return it and skip the `queryFn`
// 4. If data don't match or does not exist, run `queryFn`
// 5. store data returned by `queryFn` in the persistance layer (possible configuration in `persisterOptions`)
// 6. return fetched data
} Benefits of such implementation:
Drawbacks:
We could even start those new per-query persisters as a wrappers for |
Yes, we have to make this async, which is fine 👍
so when the persister runs and restores on page load, we don't subscribe the observer (even though it's already created). That makes sure your app renders, but it will be in So I think this drawback would be fine - Whatever we do should not run if we already have fresh data in the cache. That's why I like the idea of a wrapper around the My other idea was similar to yours, except that I was leaning more towards an So I kinda like the wrapper idea. It would also keep the size of the core package the same because it would come from the persisters. However, I think it would be harder to set it globally unless you use a default queryFn... |
@DamianOsipiuk would you like to give the wrapper function a try? I'd imagine something like:
that way, you could create your custom wrapper by moving the
|
Im not really versed in developing a library as a newbie but im very invested in seeing a solution as I have currently a react native project that could greatly benefit from separate query caches. The queries can contain several megabytes of base64 strings and loading/storing them all at once is slow with my current implementation. My hacky solution has been so far to create separate queryclients and bringing the provider down the component tree but that solution is hard to maintain. I like all proposals so far. If i understood the proposal correctly my ideal solution would be to add persiter field to useQuery hook options object that would take in an object similar to persistclient configuration. The hook would first read persister value with get callback and set the result as initialData if successful. If not successful continue with regular fetch function. If stale time is configured and hasnt elapsed it would set the initialData as data and consider the query as success. If the stale time has lapsed or persister fails to provide info the queryFn would fire based on other rules in options object. Callbacks would then fire based on queryFn results. If the queryFn is a success then persister set function would be called and new result stored in persister. If invalidateQuery is called with matching key then persister del function would be called. This would fail the persister get step next time the query is used and query would force fetch anyway. Am i correct that the proposal is at least in same spirit? Cause if yes then that would be an amazing addon to the library. Option b I also like is if the persistclient get/set functions would optionally take in a serialized key so that each query could be seperatly handled and the developer has the responsibility by writing the correct get/set/del functions. Not exactly sure what the API would look like. Perhaps createPersister(separateKeys?: boolean) or something? Not sure. In any case i wish you guys all the inspiration. Looking forward if the functionality can be implemented in any way so that the lambs are well and the wolves have eaten. |
Related:
One approach would be to have another async function that runs before the
queryFn
(and maybe one that runs after it ?) that would skip calling thequeryFn
if something other thanundefined
was returned. Here, people could read from an async storage (and potentially write to it in the "after" hook). The query could also stay infetchStatus: 'idle'
because we haven't triggered thequeryFn
yet.Combined with the possibility to customize the in-memory cache (see #4687), people would be free to keep the size of the in-memory cache small.
The text was updated successfully, but these errors were encountered: