Results should be keyed to enable individual retrieval #575
Replies: 3 comments
-
As of today, your second idea is my suggestion. RQ probably won’t have denormalized storage any time soon and for good reason in most use cases. Atomic updates of cache items and cache items groups are more reliable as long as bandwidth isn’t an issue. If you really need it though, just do as you suggested and look it up initially from the query cache. But if you do that, you’ll then have to determine if and when your parent lists items are out of date and trigger a refetch somewhere. Whether that is in the parent list and updating individual records, or if it’s in the individual item and updates the list, is up to you.
…On Jun 10, 2020, 8:46 PM -0600, CreativeTechGuy ***@***.***>, wrote:
I cannot seem to find a way to do this without some queryCache hacks, so I assume it is a missing feature.
Use-Case
I request a list of results and later wish to request a single result from the previous list. If that item is already in the previous list, I should be able to retrieve it from cache rather than the network.
Example:
// Pulls the whole list
useQuery("todos", fetchTodoList);
// Should first check if index 7 already exists in the "todo" cache and if not, run the query
useQuery(["todos", 7], fetchTodoItem);
// Should first check if an item of the "todo" cache has the matching key/value pair and if not run the query
useQuery(["todos", { uuid: "abcd" }], fetchTodoItem);
I haven't yet figured out what the best syntax would be for this, but this is a use-case I need to solve to be able to use react-query.
I can only see two ways of solving this use-case today:
• To use queryCache.subscribe to listen for "todos" being added to the cache and then using queryCache.setQueryData to add each new key to the cache. Not only does this seem really messy but it duplicates all of the data as it's all cached twice.
• In all fetch functions, first queryCache.getQuery and check if the data already exists and if not. If so, return early and if not make the request.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Beta Was this translation helpful? Give feedback.
-
I wanted to share the solution I came up with for this issue. It might be a candidate for a helper function in the library itself. const listQueryKey = ["todos"];
const itemQueryKey = ["todo", 5];
let initialData = undefined;
// Check if the item is already in cache
const isItemInCache = typeof queryCache.getQueryData(itemQueryKey) !== "undefined";
if (!isItemInCache) {
// If the item isn't in the cache, check if the list is in the cache
const cachedListData = queryCache.getQueryData(listQueryKey);
if (typeof cachedListData !== "undefined") {
// This is where the user defines the transform ["todos"] into ["todo", 5]
const prunedCache = selector(cachedListData);
// selector() can return undefined if the data it's looking for isn't there
if (typeof prunedCache !== "undefined") {
initialData = prunedCache;
}
}
}
// Finally call useQuery for the item passing in the initialData so the request doesn't happen
const queryObj = useQuery(itemQueryKey, getTodoItem, {
initialData: initialData
}); One problem that this creates is that when you clear the cache of one it isn't reflected in the other as it's copied. I wonder if the solution is for this function to somehow link these as a dependency and have the ability to refetch both when one is refetched. Or maybe there's a different approach entirely where a new query isn't created with initial data but the response is just constructed on the fly. I'm sure you could come up with an elegant way to do this in the library if you wanted to. Would you be open to a PR regarding this issue? |
Beta Was this translation helpful? Give feedback.
-
I would be more open to a contribution to the docs at this point that talks about this pattern. |
Beta Was this translation helpful? Give feedback.
-
I cannot seem to find a way to do this without some queryCache hacks, so I assume it is a missing feature.
Use-Case
I request a list of results and later wish to request a single result from the previous list. If that item is already in the previous list, I should be able to retrieve it from cache rather than the network.
Example:
I haven't yet figured out what the best syntax would be for this, but this is a use-case I need to solve to be able to use react-query.
I can only see two ways of solving this use-case today:
queryCache.subscribe
to listen for "todos" being added to the cache and then usingqueryCache.setQueryData
to add each new key to the cache. Not only does this seem really messy but it duplicates all of the data as it's all cached twice.queryCache.getQuery
and check if the data already exists and if not. If so, return early and if not make the request.Beta Was this translation helpful? Give feedback.
All reactions